Skip to content

Commit

Permalink
Merge pull request #6 from Nexters/feature/refactoring
Browse files Browse the repository at this point in the history
Feature/refactoring
  • Loading branch information
minkj1992 authored Jan 22, 2021
2 parents d25d692 + a7f21f1 commit 3a8070a
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 53 deletions.
2 changes: 1 addition & 1 deletion src/config/config.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ConfigService } from "./config.service";
providers: [
{
provide: ConfigService,
useValue: new ConfigService(".env.dev"),
useValue: new ConfigService(),
},
],
exports: [ConfigService],
Expand Down
5 changes: 3 additions & 2 deletions src/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import * as fs from "fs";
export class ConfigService {
private readonly envConfig: { [key: string]: string };

constructor(filePath: string) {
console.log(`제민욱${process.env.NODE_ENV}`);
constructor() {
console.log(`${process.env.NODE_ENV}`);

if (process.env.NODE_ENV === "prod") {
this.envConfig = {
Expand All @@ -24,6 +24,7 @@ export class ConfigService {
MONGO_CACHE_NAME: process.env.MONGO_CACHE_NAME,
};
} else {
const filePath = ".env.dev";
this.envConfig = dotenv.parse(fs.readFileSync(filePath));
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ async function bootstrap() {
logger: ["error", "warn"],
});

const configService = new ConfigService(".env.dev");
const configService = new ConfigService();

app.enableCors();
// app.setGlobalPrefix(configService.get("NODE_ENV"));

await app.listen(process.env.PORT || configService.get("NODE_PORT"));
console.log(`Application is running on: ${await app.getUrl()}`);
}
Expand Down
2 changes: 1 addition & 1 deletion src/place/kakaoMapSearch/search.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
registerEnumType,
} from "@nestjs/graphql";

enum SortType {
export enum SortType {
distance = "distance",
accuracy = "accuracy",
}
Expand Down
55 changes: 47 additions & 8 deletions src/place/kakaoMapSearch/search.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import Axios, { AxiosResponse } from "axios";
import { Injectable, Inject, CACHE_MANAGER } from "@nestjs/common";
import {
Injectable,
Inject,
CACHE_MANAGER,
HttpException,
HttpStatus,
} from "@nestjs/common";
import { Cache } from "cache-manager";

import { CreateSpotInput } from "src/spot/dto/create-spot.input";
import { ConfigService } from "../../config/config.service";
import { KeywordSearchDto } from "./search.dto";
import { Place } from "../place.entity";
import { SortType } from "src/place/kakaoMapSearch/search.dto";

@Injectable()
export class SearchService {
Expand All @@ -13,9 +22,7 @@ export class SearchService {
) {}

// https://developers.kakao.com/docs/latest/ko/local/dev-guide#search-by-keyword
async searchByKeyworld(
keywordSearchDto: KeywordSearchDto
): Promise<void | AxiosResponse<object>> {
async searchByKeyword(keywordSearchDto: KeywordSearchDto): Promise<Place[]> {
const baseUrl = this.configService.get("KAKAO_DEV_HOST");
return Axios.get(baseUrl, {
headers: {
Expand All @@ -28,14 +35,46 @@ export class SearchService {
},
})
.then((response) => response.data.documents)
.catch((err) => console.error(err));
.catch((err) => {
if (err.response.status == 400) {
console.error(err.response);
throw new HttpException("no matched place", HttpStatus.BAD_REQUEST);
} else {
console.error(err.response);
throw new HttpException(
"kakao api server error",
HttpStatus.INTERNAL_SERVER_ERROR
);
}
});
}

// https://github.com/BryanDonovan/node-cache-manager
async setPlaceFromCacheById(key, value) {
return this.cacheManager.set(key, value);
this.cacheManager.set(key, value, { ttl: 300 }, function (err) {
console.error(err);
throw new HttpException(
"set place cache error",
HttpStatus.INTERNAL_SERVER_ERROR
);
});
}

async getPlaceFromCacheById(key) {
return this.cacheManager.get(key);
async getPlaceFromCacheById(id): Promise<Place> {
return this.cacheManager.get(id);
}

async getIdenticalPlace(
createSpotInput: CreateSpotInput
): Promise<Place | null> {
const places: Place[] = await this.searchByKeyword({
query: createSpotInput.place_name,
x: createSpotInput.x,
y: createSpotInput.y,
radius: 1,
sort: SortType.distance,
});
console.log(places);
return places.length >= 1 ? places[0] : null;
}
}
2 changes: 1 addition & 1 deletion src/place/place.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Field, ObjectType, Float } from "@nestjs/graphql";
// https://developers.kakao.com/docs/latest/ko/local/dev-guide#search-by-keyword
@ObjectType()
export class Place {
@Field(() => String)
@Field(() => String, { description: "kakao place id" })
id: string;

@Field(() => String)
Expand Down
37 changes: 23 additions & 14 deletions src/place/place.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Args, Query, Resolver } from "@nestjs/graphql";

import { HttpException, HttpStatus } from "@nestjs/common";
import { Place } from "./place.entity";
import { SearchService } from "./kakaoMapSearch/search.service";
import { KeywordSearchDto } from "./kakaoMapSearch/search.dto";
Expand All @@ -9,25 +9,34 @@ export class PlaceResolver {
constructor(private readonly searchService: SearchService) {}

@Query(() => [Place])
async placesByKeyworld(
async placesByKeyword(
@Args("filters") filters: KeywordSearchDto
): Promise<object> {
const places: any = await this.searchService.searchByKeyworld(filters);

for await (let p of places) {
const isCached = await this.searchService.getPlaceFromCacheById(p.id);
console.log(isCached);
if (isCached) continue;
this.searchService.setPlaceFromCacheById(p.id, p);
}
const places: Place[] = await this.searchService.searchByKeyword(filters);
places.forEach(async (place) => {
const cachedPlace: Place | null = await this.searchService.getPlaceFromCacheById(
place.id
);
const isCached = cachedPlace !== null;
isCached || this.searchService.setPlaceFromCacheById(place.id, place);
});
return places;
}

// get place from cache (for test)
@Query(() => Place)
async getPlace(
async getPlaceFromCache(
@Args("placeId", { type: () => String }) placeId: string
): Promise<Place | void> {
return await this.searchService.getPlaceFromCacheById(placeId);
): Promise<Place | HttpException> {
const cachedPlace: Place | null = await this.searchService.getPlaceFromCacheById(
placeId
);

if (cachedPlace === undefined) {
return new HttpException(
`There is no cached place with ${placeId}`,
HttpStatus.BAD_REQUEST
);
}
return cachedPlace;
}
}
10 changes: 6 additions & 4 deletions src/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
# ------------------------------------------------------

type Spot {
"""카카오 Place id"""
"""kakao place id"""
id: String!

"""emoji id list"""
"""list of emoji ids"""
emojis: [String!]!
place_name: String!
category_name: String
Expand All @@ -17,11 +17,13 @@ type Spot {
road_address_name: String
place_url: String
distance: String
location: String!
x: Float
y: Float
}

type Place {
"""kakao place id"""
id: String!
place_name: String!
category_name: String
Expand All @@ -44,8 +46,8 @@ type DeleteSpotDto {

type Query {
findSpots: [Spot!]!
placesByKeyworld(filters: KeywordSearchDto!): [Place!]!
getPlace(placeId: String!): Place!
placesByKeyword(filters: KeywordSearchDto!): [Place!]!
getPlaceFromCache(placeId: String!): Place!
}

input KeywordSearchDto {
Expand Down
28 changes: 20 additions & 8 deletions src/spot/entities/spot.entity.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { ObjectType, Field, Int, Float } from "@nestjs/graphql";
import { ObjectType, Field, ID, Int, Float } from "@nestjs/graphql";
import * as mongoose from "mongoose";
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";

@ObjectType()
@Schema({ timestamps: true }) // graphql 은 timestamp 삽입 어떻게 할까?
export class Spot {
@Prop({ required: true, unique: true })
@Field(() => String, { description: "카카오 Place id" })
@Field(() => String, { description: "kakao place id" })
id: string;

@Prop({ required: true })
@Field((type) => [String], { description: "emoji id list" })
@Field((type) => [String], { description: "list of emoji ids" })
emojis: string[];

@Prop({ required: true })
Expand Down Expand Up @@ -49,18 +49,30 @@ export class Spot {
@Prop()
distance?: string;

@Field(() => String)
@Prop({
type: {
type: String,
enum: ["Point"],
default: "Point",
required: true,
},
coordinates: {
type: [Number],
required: true,
index: "2dsphere",
default: [0, 0],
},
})
location: string;

@Field((type) => Float, { nullable: true })
@Prop()
x?: number;

@Field((type) => Float, { nullable: true })
@Prop()
y?: number;

// https://github.com/LotfiMEZIANI/Three-in-one-blog-post/blob/8cc58d094bad5c1a3ca0514ec1d6a6282724313b/src/app/person/person.model.ts#L19
// @Field(() => [Emoji])
// @Prop({ type: [mongoose.Types.ObjectId], ref: Emoji.name })
// emojis: mongoose.Types.ObjectId[] | Emoji[];
}

export type SpotDocument = Spot & mongoose.Document;
Expand Down
18 changes: 14 additions & 4 deletions src/spot/spot.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Resolver, Query, Mutation, Args, Int } from "@nestjs/graphql";
import { Resolver, Query, Mutation, Args, Int, Float } from "@nestjs/graphql";
import { SpotService } from "src/spot/spot.service";
import { Spot } from "src/spot/entities/spot.entity";
import { CreateSpotInput } from "src/spot/dto/create-spot.input";
Expand All @@ -10,13 +10,15 @@ export class SpotResolver {
constructor(private readonly spotService: SpotService) {}

@Mutation(() => Spot)
async createSpot(@Args("createSpotInput") createSpotInput: CreateSpotInput) {
async createSpot(
@Args("createSpotInput") createSpotInput: CreateSpotInput
): Promise<Spot> {
const spot = await this.spotService.findOne(createSpotInput.id);

if (spot === null) {
return this.spotService.create(createSpotInput);
return await this.spotService.create(createSpotInput);
} else {
return this.spotService.update(spot, createSpotInput.emoji);
return await this.spotService.update(spot, createSpotInput.emoji);
}
}

Expand All @@ -25,6 +27,14 @@ export class SpotResolver {
return await this.spotService.findAll();
}

// @Query(() => [Spot])
// async getSpots(
// @Args("x", { type: () => Float }) x: number,
// @Args("y", { type: () => Float }) y: number
// ) {
// return await this.spotService.getSpot(x, y);
// }

// @Query(() => Spot, { name: "spot" })
// async findOne(@Args("id", { type: () => Int }) id: number) {
// return this.spotService.findOne(id);
Expand Down
Loading

0 comments on commit 3a8070a

Please sign in to comment.