GraphQL๊ณผ Apollo ์—ด ํ•œ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - TypeScript + Nest.js์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ

2023. 12. 5. 00:45ใ†Back-End ์ž‘์—…์‹ค/Nest.js

728x90
๋ฐ˜์‘ํ˜•

 

 

 

์นด์นด์˜คํŽ˜์ด | ๋งˆ์Œ ๋†“๊ณ  ๊ธˆ์œตํ•˜๋‹ค

์—ฌ๊ธฐ๋ฅผ ๋ˆŒ๋Ÿฌ ๋งํฌ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

qr.kakaopay.com

 

 

 

 

 

NestJS๋กœ ๋ฐฐ์šฐ๋Š” ๋ฐฑ์—”๋“œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ:ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์˜ ์ฐจ์„ธ๋Œ€ ์„œ๋ฒ„ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋‚˜๋‹ค

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 




๐Ÿ—‚ ๋ชฉ์ฐจ

โœ… GraphQL๊ณผ Apollo ์ฒซ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - ๊ฐœ๋… ์ตํžˆ๊ธฐ
โœ… GraphQL๊ณผ Apollo ๋‘๋ฒˆ์งธ ์ด์•ผ๊ธฐ - REST API๋ž€?
โœ… GraphQL๊ณผ Apollo ์„ธ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL์˜ ์ •๋ณด ์ฃผ๊ณ  ๋ฐ›๋Š” ๋ฐฉ์‹

โœ… GraphQL๊ณผ Apollo ๋„ค๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Apollo๋ž€?
โœ… GraphQL๊ณผ Apollo ๋‹ค์„ฏ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด ๋ณด์•„์š” ๐Ÿ˜€
โœ… GraphQL๊ณผ Apollo ์—ฌ์„ฏ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL Moduleํ™”์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š” ๐Ÿ˜€
โœ… GraphQL๊ณผ Apollo ์ผ๊ณฑ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL Data Type์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š” ๐Ÿ˜€
โœ… GraphQL๊ณผ Apollo ์—ฌ๋Ÿ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL Union๊ณผ Interface ๊ทธ๋ฆฌ๊ณ  ์ธ์ž์™€ ์ธํ’‹ ํƒ€์ž…์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š” ๐Ÿ˜€
โœ… GraphQL๊ณผ Apollo ์•„ํ™‰๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Java + Spring Boot์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ
โœ… GraphQL๊ณผ Apollo ์—ด๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Java + Spring Boot์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ•ด๋ณด๊ธฐ
โœ… GraphQL๊ณผ Apollo ์—ด ํ•œ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - TypeScript + Nest.js์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ
โœ… 
GraphQL๊ณผ Apollo ์—ด ๋‘๋ฒˆ์งธ ์ด์•ผ๊ธฐ - TypeScript + Nest.js์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ํ…Œ์ŠคํŠธ
โœ… GraphQL๊ณผ Apollo ์—ด ์„ธ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - TypeScript + Nest์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ•ด๋ณด๊ธฐ
โœ… 
GraphQL๊ณผ Apollo ์—ด ๋„ค๋ฒˆ์งธ ์ด์•ผ๊ธฐ - React์™€ Apollo Client
โœ… GraphQL๊ณผ Apollo ์—ด๋‹ค์„ฏ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - React์™€ Apollo Client - Query์™€ Mutation ์‚ฌ์šฉํ•˜์—ฌ ์›น ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ
โœ… GraphQL๊ณผ Apollo ์—ด ์—ฌ์„ฏ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Kotlin + Spring Boot์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ
โœ… GraphQL๊ณผ Apollo ์—ด ์ผ๊ณฑ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Kotlin + Spring Boot์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ•ด๋ณด๊ธฐ


๐Ÿค” ๋‚ด๊ฐ€ ๋งŒ๋‚œ ๋ฌธ์ œ

โš ๏ธ [Nest.js] TypeORM Table ๊ด€๊ณ„๊ฐ€ ๋งบ์–ด์กŒ์„ ๋•Œ, Seeding (feat. Migration)
โš ๏ธ [Spring Boot 3.0] Could not resolve org.springframework.boot:spring-boot-gradle-plugin
โš ๏ธ [Spring Boot 3] Spring Doc(Swagger) White Label Error


๐Ÿ“‹ ๋ถ€๋ก

๐Ÿ” [Nest.js] ์ดˆ๊ธฐ ํ™˜๊ฒฝ ๊ตฌ์„ฑ (feat. TypeORM, QueryBuilder, GraphQL, Apollo)
๐Ÿ” [SOLID][Nest.js][Java + Spring] Interface๋ฅผ ํ™œ์šฉํ•œ ๊ฒฐํ•ฉ๋„ ๋ถ„๋ฆฌ (Interface๋ฅผ ์ด์šฉํ•œ Dependency Injection - DI)

 

 

 

GitHub - junyharang-coding-study/GraphQL-Study: GraphQL์„ ๊ณต๋ถ€ํ•˜๊ณ , ์‹ค์Šตํ•œ ์ฝ”๋“œ์—์š” ๐Ÿ˜€

GraphQL์„ ๊ณต๋ถ€ํ•˜๊ณ , ์‹ค์Šตํ•œ ์ฝ”๋“œ์—์š” ๐Ÿ˜€. Contribute to junyharang-coding-study/GraphQL-Study development by creating an account on GitHub.

github.com

 

 

 

 

๐Ÿš€ GraphQL๊ณผ Apollo ์—ด ํ•œ๋ฒˆ์งธ ์ด์•ผ๊ธฐ

    ๐Ÿ”ฝ TypeScript + Nest.js์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ

        ๐Ÿ“ฆ ๊ฐœ์š”

์ด ์ „ ์‹œ๊ฐ„๊นŒ์ง€ ์ฃผ๋‹ˆ๋Š” ์žํ”„๋ง๊ณผ JPA ๊ทธ๋ฆฌ๊ณ  QueryDsl ORM์„ ์‚ฌ์šฉํ•˜์—ฌ GraphQL์— ๋Œ€ํ•ด ๊ตฌ์„ฑํ•˜๊ณ ,
์‹ค์Šตํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ๋ณด์•˜์–ด์š”.

์š”์ฆ˜ ์ทจ์—… ์‹œ๊ฐ„์„ ๋‘˜๋Ÿฌ๋ณด๋‹ˆ ๋งŽ์€ ๊ธฐ์—…์—์„œ Nest.js๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์„ ์ฐพ๋Š” ๊ฒƒ์„ ๋ณด์•˜๊ณ , ๋”๋ถˆ์–ด GraphQL ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์‚ฌ๋žŒ์„ ์ฐพ๋Š” ๊ณต๊ณ ๋ฅผ ๋งŽ์ด ๋ณด๊ฒŒ ๋˜์—ˆ์–ด์š”.

๊ธฐ์—…์—์„œ ํ•„์š”๋กœ ํ•˜๋Š” ๊ธฐ์ˆ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น Computer(์ปดํ“จํ„ฐ) Languge(์–ธ์–ด)์™€ Framwork(ํ”„๋ ˆ์ž„์›Œํฌ)๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค์‹œ ์‹ค์Šตํ•ด ๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ์—ด๋‘๋ฒˆ์งธ ์ด์•ผ๊ธฐ์—์„œ ์‚ฌ์šฉํ•  ORM์€ TypeORM์„ ์‚ฌ์šฉํ•  ๊ฑฐ์—์š”.

๋˜ํ•œ, GraphQL์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉฐ ๊ณต๋ถ€ํ–ˆ๋˜ Apollo๋ฅผ ์‚ฌ์šฉํ•  ๊ฑฐ์—์š”.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ดˆ๊ธฐ ๊ตฌ์„ฑ ์ •๋ณด๋Š” ์ด ๊ณณ์— ๋”ฐ๋กœ ์ž‘์„ฑํ•ด ๋‘์—ˆ์–ด์š”.

 

 

 

 

  

๐Ÿš€ ์ฝ”๋“œ ๊ตฌํ˜„

    ๐Ÿ”ฝ Equipment - Resolver

        ๐Ÿ“ฆ ์ดˆ๊ธฐ ๊ตฌ์„ฑ

nest generate resolver <๋งŒ๋“ค ์œ„์น˜>/<ํŒŒ์ผ๋ช…>


Nest.js๋Š” @nestjs/cli ํŒจํ‚ค์ง€์˜ nest generate ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ํŒŒ์ผ๋“ค์„ ๋งŒ๋“ค์–ด ์ค„ ์ˆ˜ ์žˆ์–ด์š”.
์œ„์™€ ๊ฐ™์ด ์ž…๋ ฅํ•˜๋ฉด resolver๋ฅผ ์›ํ•˜๋Š” ์œ„์น˜์— ๋งŒ๋“ค์–ด ์ค„ ์ˆ˜ ์žˆ์–ด์š”.


NestCLI ๋ช…๋ น์–ด


๊ทผ๋ฐ, ์ฃผ๋‹ˆ๊ฐ€ ์›ํ•œ ๊ฑด src/app/equipment/resolver/Equipment๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ธธ ๋ฐ”๋žฌ์ง€๋งŒ,
src/app/equipment/resolver/equipment/ ์ด ๊ณณ์— ๋งŒ๋“ค์–ด์ง„ ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์–ด์š”.

src/app/equipment/resolver


๊ทธ๋ž˜์„œ ์œ„์น˜๋ฅผ ์œ„์™€ ๊ฐ™์ด ๋ณ€๊ฒฝํ•ด ์ฃผ์—ˆ์–ด์š”.

src/app/equipment/resolver/equipment.resolver.ts (๋ณ€๊ฒฝ ์ „)


์„ผ์Šค์žˆ๊ฒŒ @Resolver()๊ฐ€ ๋”ฑ ๋ถ™์–ด์žˆ๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”.

์ด์ œ ์ด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ด ๋ณผ๊ฒŒ์š”.





        ๐Ÿ“ฆ Create

src/app/equipment/resolver/equipment.resolver.ts


์œ„ ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋ถ„์„ํ•ด ๋ณผ๊ฒŒ์š”.

์ฝ”    ๋“œ ์ƒ ์„ธ ๋‚ด ์šฉ
@Resolver(...) ํ•ด๋‹น Class๊ฐ€ GraphQL Resolver์ž„์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ,
EquipmentEntity์— ๋Œ€ํ•œ GraphQL Resolver๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ •์˜.
EquipmentResolver Class EquipmentEntity์— ๋Œ€ํ•œ GraphQL Resolver ์ •์˜ Class.
Resolver๋Š” GraphQL Query, Mutaion์— ๋Œ€ํ•œ ์‹ค์ œ Logic ๋‹ด๋‹น.
constructor(...) ์ƒ์„ฑ์ž ๋ถ€๋ถ„์œผ๋กœ Class๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ, ํ˜ธ์ถœ๋˜๋Š” Method.

์ฃผ์ž…๋œ equipmentService๋ฅผ ํ•ด๋‹น ๊ฐ์ฒด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ดˆ๊ธฐํ™”
@UsePips(...) ํ•ด๋‹น Mutaion์˜ ์ธ์ž์— ๋Œ€ํ•œ ์ž…๋ ฅ๊ฐ’์„ ๊ฒ€์ฆํ•˜๊ณ , ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” Pipe ์ง€์ •.
ValidationPipe๋Š” ์ฃผ์–ด์ง„ DTO(Data Transfer Object) Class์— ๋”ฐ๋ผ ์ž…๋ ฅ๊ฐ’์„ ๊ฒ€์ฆํ•˜๊ณ , ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ณ€ํ™˜ ์ž‘์—… ์ˆ˜ํ–‰(gransfrom: true).
@Mutaion(...) GraphQL Mutaion ์ •์˜.
DefaultResponse<string>์€ ํ•ด๋‹น Mutaion์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ํ‘œํ˜„.
saveForEquipment() @Mutaion์œผ๋กœ GraphQL Mutaion Method์ž„์„ ์ •์˜.
EquipmentRequestDto๋ฅผ ์ž…๋ ฅ ๋ฐ›์•„ equipmentService์˜ saveForEquipment() ํ˜ธ์ถœํ•œ ๋’ค ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜.
@Args(...) GraphQL Mutaion์˜ ์ธ์ž ์ •์˜๋ฅผ ์œ„ํ•œ Decorator.
"input"์€ ํ•ด๋‹น ์ธ์ž์˜ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, { type: () => EquipmentResponseDto }๋Š” ์ด ์ธ์ž Type์ด EquipmentRequestDto ๊ฐ์ฒด์ž„์„ ๋ช…์‹œ.
@Body() ... Nest.js์˜ @Body()๋ฅผ ์ด์šฉํ•˜์—ฌ HTTP Request Body์—์„œ Data ์ถ”์ถœ์„ ๋ช…๋ น.
์—ฌ๊ธฐ์„œ equipmentRequestDto๋Š” ํ•ด๋‹น Mutaion์˜ ์‹ค์ œ ์ธ์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด.
Mutation ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋กœ DefaultResponse<string> ๊ฐ์ฒด ๋ฐ˜ํ™˜.


์—ฌ๊ธฐ์„œ Promise์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž๋ฉด Promise๋Š” JavaScript์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋‹ค๋ฃฐ ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด์—์š”.
์ด๋Š” ํŠน์ • ์ž‘์—…์˜ ์™„๋ฃŒ ๋˜๋Š” ์‹คํŒจ์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š”๋ฐ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์–ด์š”.

JavaScript๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด Call Back(์ฝœ๋ฐฑ) ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋„ˆ๋ฌด ๋‚จ์šฉํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด
์ฝœ๋ฐฑ ์ง€์˜ฅ์— ๋น ์งˆ ์ˆ˜ ์žˆ๊ฒŒ ๋ผ์š”.


์ด๋ ‡๊ฒŒ ๋˜๋ฉด Error ์ฒ˜๋ฆฌ๋„ ํž˜๋“ค๊ณ , ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋ฒˆ์— ํ•˜๋Š”๋ฐ ํ•œ๊ณ„๊ฐ€ ๋ฐœ์ƒํ•  ๊ฑฐ์—์š”.
์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ๋ณด์™„ํ•˜๋ฉฐ, ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Promise๊ฐ€ ํƒ„์ƒํ•˜๊ฒŒ ๋˜์—ˆ์–ด์š”.

Promise๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์‹œ์ ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ณ , ์—ฐ์†๋œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ž‘์—…์„ ์ˆ˜์ •, ์‚ญ์ œ, ์ถ”๊ฐ€ํ•˜๊ธฐ ํŽธํ•˜๊ณ  ์œ ์—ฐํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ , Code์˜ ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ๋ณด๋‹ค ํŽธ๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

Promise๋Š” ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ์Šคํ„ด์Šค์™€ ํ•  ์ˆ˜ ์žˆ์–ด์š”.
Promise์˜ ์ƒ์„ฑ์ž๋Š” resolve์™€ reject ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ ๋ฐ›๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ณ  ์žˆ์–ด์š”.
Promise๋Š” ์ธ์ž๋กœ ์ „๋‹ฌ ๋ฐ›์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋‚ด๋ถ€์—์„œ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌ ํ•œ๋‹ต๋‹ˆ๋‹ค. 


Promise ๊ฐ์ฒด๋Š” ์„ธ ๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด์š”.

์ƒ    ํƒœ ์ƒ์„ธ ๋‚ด์šฉ
Pending(๋Œ€๊ธฐ ์ค‘) ๋น„๋™๊ธฐ ์ž‘์—…์ด ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์ƒํƒœ. ์ฆ‰, ์ดˆ๊ธฐ ์ƒํƒœ.
Fulfilled(์ดํ–‰ ๋จ) ๋น„๋™๊ธฐ ์ž‘์—… ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ์ƒํƒœ.
Rejected(๊ฑฐ๋ถ€๋จ) ๋น„๋™๊ธฐ ์ž‘์—… ์‹คํŒจ ์ƒํƒœ.
728x90

 

const myPromise = new Promise((resolve, reject) => {
  // ๋น„๋™๊ธฐ ์ž‘์—… ์ˆ˜ํ–‰
  // ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๋ฉด resolve() ํ˜ธ์ถœ
  // ์ž‘์—…์ด ์‹คํŒจํ•˜๋ฉด reject() ํ˜ธ์ถœ
});

myPromise.then(
  (result) => {
    // ์ž‘์—…์ด ์„ฑ๊ณตํ–ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ๋ถ€๋ถ„
  },
  (error) => {
    // ์ž‘์—…์ด ์‹คํŒจํ–ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ๋ถ€๋ถ„
  }
);


์œ„ Code๋Š” Promise์˜ ๊ตฌ์กฐ๋ฅผ ๋‚˜ํƒ€๋‚ธ Code์—์š”.

resolve์™€ reject๋Š” Promise ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋‘ ๊ฐœ์˜ ํ•จ์ˆ˜์—์š”.
resolve ํ•จ์ˆ˜๋Š” ์ž‘์—…์ด ์„ฑ๊ณต๋˜์—ˆ์„ ๋•Œ ํ˜ธ์ถœ๋˜๊ณ , reject ํ•จ์ˆ˜๋Š” ์ž‘์—…์ด ์‹คํŒจํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ ๋œ๋‹ต๋‹ˆ๋‹ค.


src/app/equipment/resolver/equipment.resolver.ts


์œ„ Code์—์„œ Promise<DefaultResponse<string>> ์ด๋ผ๋Š” ์˜๋ฏธ๋Š” Promise ๊ฐ์ฒด๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ดํ–‰ ๋˜๋ฉด DefaultResponse<string> ํ˜•ํƒœ์˜ Data๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ด๋ผ๋Š” ์˜๋ฏธ์—์š”.




 

        ๐Ÿ“ฆ RequestDto

src/app/equipment/model/dto/request/equipment-request.dto.ts


์ €์žฅ์„ ์œ„ํ•œ RequestDto์—์š”.

@InputType()์€ ํ•ด๋‹น DTO๊ฐ€ GraphQL์˜ InputyType์ด๋ผ๊ณ  ๋ช…์‹œํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.
์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด GraphQL Query๋‚˜, Mutation์— ์ „๋‹ฌ๋˜๋Š” ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ํ˜•ํƒœ๋ฅผ ์ •์˜ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋ž๋‹ˆ๋‹ค.

@Field(...)์™€ ๊ฐ™์€ Decorator๋Š” ํ•ด๋‹น Field๊ฐ€ GraphQL์—์„œ ์–ด๋–ค ์ž๋ฃŒํ˜• Type์„ ๊ฐ–๋Š”์ง€ ์ •์˜ํ•ด ์ฃผ๋Š” ๋ถ€๋ถ„์ด์—์š”.
๊ทธ๋ฆฌ๊ณ , @IsNotEmpty(), @IsInt(), @Min(), @IsString()์€ class-validator์˜ Decorator๋กœ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด ๋ช…์‹œํ•ด ์ค€ Decorator์—์š”.

toEntity()๋Š” ํ•ด๋‹น DTO ๊ฐ์ฒด์˜ ๊ฐ’์„ Entity ๊ฐ์ฒด ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ์นœ๊ตฌ์—์š”.




        ๐Ÿ“ฆ Read - ๋ชฉ๋ก์กฐํšŒ

src/app/equipment/resolver/equipment.resolver.ts


์œ„ ์ฝ”๋“œ๋Š” ๋ชฉ๋ก์กฐํšŒ๋ฅผ ์œ„ํ•œ ์ฝ”๋“œ์—์š”.
๋ชฉ๋ก์กฐํšŒ ๋ฉ”์„œ๋“œ๋Š” ๊ฒ€์ƒ‰๊ณผ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ™์ด ๋˜๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

์ฝ”    ๋“œ ์ƒ ์„ธ ๋‚ด ์šฉ
@Query(...) GqphQL Query๋ฅผ ์ •์˜ํ•˜๋Š” Decorator.
DefaultResponse<EquipmentResponseDto[]>๋Š” ํ•ด๋‹น Query๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” Data Type ํ‘œํ˜„.

์œ„ ๋‚ด์šฉ์€ ๋ฐฐ์—ด ํ˜•ํƒœ์˜ EquipmentResponseDto๋ฅผ ๊นœ์‹ผ DefaultResponse ๋ผ๋Š” ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ์˜๋ฏธ.
@Args(...) GraphQL Query ์ธ์ž ์ •์˜.

"usedBy", { type: () => String, nullable: true }) usedBy: string

- usedBy: ์ธ์ž์˜ ์ด๋ฆ„ ์ •์˜.
- { type: () => String, nullable: true }: ํ•ด๋‹น ์ธ์ž Type์ด ๋ฌธ์ž์—ด์ด๊ณ , nullable: true๋ฅผ ํ†ตํ•ด ์ธ์ž๊ฐ€
   ์„ ํƒ์ ์ž„์„ ํ‘œํ˜„. 
์ฆ‰, ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ์˜๋ฏธ.
- usedBy: string: ํ•ด๋‹น ์ธ์ž๋ฅผ ๋ฐ›์•„๋“ค์ด๋Š” ๋ณ€์ˆ˜์˜ Type ์ •์˜.


์กฐํšŒํ•  ์ธ์ž๋Š” ๊ผญ ํ•„์š”ํ•œ ๊ฐ’์€ ์•„๋‹ˆ์—์š”.
๊ทธ๋ฆฌ๊ณ , page์™€ perPageSize๋Š” ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ธ์ž์ด๊ณ ,
orderBy๋Š” ๋ง ๊ทธ๋Œ€๋กœ ์ •๋ ฌ์„ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ์ธ์ง€ ์„ ํƒํ•˜๋ผ๊ณ  ๋ฐ›์•„์ฃผ๋Š” ๋ถ€๋ถ„์ด์—์š”.

 

 

 

        ๐Ÿ“ฆ Read - ์ƒ์„ธ์กฐํšŒ

src/app/equipment/resolver/equipment.resolver.ts


์ด ์ฝ”๋“œ์—์„œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ ์€ @Args์˜ Property์ด input์ด ์•„๋‹Œ equipmentId๋ผ๋Š” ์ ์ด์—์š”.

๋ฐ‘์—์„œ ๋˜ ์ž์„ธํžˆ ์ด์•ผ๊ธฐ ํ•˜๊ฒ ์ง€๋งŒ

src/graphql/schema/schema.graphqls


GraphQL type Root Query์™€ type Root Mutation์„ ๋ณด๋ฉด
saveForEquipment()๋Š” input์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ฃผ๊ฒ ๋‹ค๊ณ  ์„ ์–ธํ•˜์˜€์œผ๋‚˜,

getEquipment()๋Š” ์ธ์ž๊ฐ’์œผ๋กœ equipmentId๋ฅผ ์ค„๊ฑด๋ฐ, ๊ทธ๊ฑด ๋ฌธ์ž์—ด์ด์•ผ! ๋ผ๊ณ  ์•Œ๋ ค์ค€ ๊ฒƒ์ด์—์š”.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— @Args์˜ Property๊ฐ€ input์ด ์•„๋‹Œ equipmentId๋กœ ์ž‘์„ฑํ•ด ์ฃผ์–ด์•ผ ํ•ด์š”.





        ๐Ÿ“ฆ Update

src/app/equipment/resolver/equipment.resolver.ts


์ €์žฅ์„ ํ•  ๋•Œ๋Š” ๊ฐ์ฒด์— ๋‹ด์•„์„œ ๊ฐ’์„ ๋ฐ›๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๊ฐ๊ฐ์˜ ์š”์†Œ๋“ค์„ ๋‚˜๋ˆ ์„œ ๋ฐ›์•„
Service์—์„œ DTO๋กœ ํ•ฉ์ณ ์ž‘์—…์„ ํ•ด ๋ณด์•˜์–ด์š”.

Update๋Š” ๊ฐ์ฒด๋กœ ์š”์ฒญ์„ ๋ฐ›๋„๋ก ์ฒ˜๋ฆฌํ•ด ๋ณด์•˜์–ด์š”.

์—ฌ๊ธฐ์„œ RequestDTO๊ฐ€ ์™œ? Updateํ•˜๊ณ , Create์—์„œ ๊ฐ๊ฐ ๋งŒ๋“ค์–ด์„œ ์ž‘์—…ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•˜์‹  ๋ถ„๋“ค์ด ๊ณ„์‹ค๊ฑฐ์—์š”.
๊ผญ ์ด๋ ‡๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์•„๋‹ˆ๊ฒ ์ง€๋งŒ, ์ฃผ๋‹ˆ๊ฐ€ ์ด๋ ‡๊ฒŒ ํ•œ ์ด์œ ๋Š”

Update์˜ ๊ฒฝ์šฐ ID๊ฐ’์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌ๋ฅผ ํ•ด์•ผ ๋˜์„œ ํ•„์ˆ˜๋กœ ๋ฐ›์•„์•ผ ํ•˜์ง€๋งŒ,
๋‚˜๋จธ์ง€ ๊ฐ’๋“ค์€ ํ•„์ˆ˜๋กœ ๋ฐ›์ง€ ์•Š์•„๋„ ๋˜๋Š”๋ฐ, Create ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์ด์™€ ๋‹ฌ๋ฆฌ ์•ˆ ๋ฐ›์•„๋„ ๋˜๋Š” ๋‚ด์šฉ์ด ์žˆ์ง€ ์•Š๋Š” ํ•œ ๋ชจ๋“  ๋‚ด์šฉ์„ ๋‹ค ๋ฐ›์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.


src/app/equipment/model/dto/request/equipment-update-request.dto.ts


๊ทธ๋ž˜์„œ UpdateRequestDTO ๊ฐ™์€ ๊ฒฝ์šฐ ID๋ฅผ ๋นผ๊ณ ๋Š” @IsNotEmpty()๋ฅผ ๋ชจ๋‘ ์ œ๊ฑฐํ•ด ์ฃผ์—ˆ๊ณ ,
toEntity() ๊ฐ™์€ ๊ฒฝ์šฐ๋„ ID๊ฐ’์„ ๋ฐ”๊พธ๋ฉด ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— ID๋Š” ์ œ์™ธํ•˜๊ณ , Entity ๊ฐ์ฒด๋กœ ๋ฐ”๋€” ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.







        ๐Ÿ“ฆ Delete

src/app/equipment/resolver/equipment.resolver.ts







 

 

    ๐Ÿ”ฝ Equipment - Service

        ๐Ÿ“ฆ Create

src/app/equipment/service/equipment.service.ts


@Injectable()์€ Nest.js์—์„œ ์ฃผ์ž… ๊ฐ€๋Šฅํ•œ(Dependency-injectable) ์„œ๋น„์Šค์ž„์„ ๋‚˜ํƒ€๋‚ด ์ฃผ๊ณ  ์žˆ์–ด์š”.
์ฃผ๋กœ Dependency Injection(์˜์กด์„ฑ ์ฃผ์ž… - DI)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ Class(ํด๋ž˜์Šค), Compnent(์ปดํฌ๋„ŒํŠธ)์— ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๊ณ , Application(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜) Module(๋ชจ๋“ˆ)์—์„œ ์ด ์„œ๋น„์Šค๋ฅผ Provider(ํ”„๋กœ๋ฐ”์ด๋”)๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ @Injectable()์„ ๋ช…์‹œํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๋Š” Nest.js์—์„œ ์˜์กด์„ฑ์„ ์ฃผ์ž… ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ฃผ์ž… ๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค๋กœ ์„ ์–ธ๋œ ํด๋ž˜์Šค๋Š” ๋‹ค๋ฅธ Nest.js ๊ตฌ์„ฑ ์š”์†Œ(Controller ๋“ฑ)์— ์ฃผ์ž…๋  ์ˆ˜ ์žˆ์–ด์š”.
@Injectable()์€ ์ฃผ๋กœ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด๋‚˜, ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค์™€ ๊ฐ™์€ ๊ณ„์ธต์— ๋งŽ์ด ์‚ฌ์šฉ๋ผ์š”.

๊ทธ๋ฆฌ๊ณ , ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด EquipmentRepository๋ฅผ ์ฃผ์ž… ๋ฐ›๊ณ  ์žˆ์–ด์š”.

15 ~ 16๋ฒˆ์งธ ์ค„์€ RequestDTO๊ฐ€ ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•ด์„œ ๋น„์–ด ์žˆ์œผ๋ฉด Error Code๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ถ€๋ถ„์ด์—์š”.

19๋ฒˆ์งธ ์ค„์€ RequestDTO์˜ equipmentId๊ฐ’์„ findByEquipmentId()์—๊ฒŒ ์ „๋‹ฌํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํ•ด๋‹น ID๊ฐ’์„ ๊ฐ–์€ ๋‚ด์šฉ์„ ๊ฐ–๊ณ ์˜ค๊ธฐ ์œ„ํ•œ ๋ถ€๋ถ„์ด๊ณ ,

์ด๋ฅผ ํ†ตํ•ด 21 ~ 23๋ฒˆ์งธ ์ค„์— ํ•ด๋‹น ๊ฐ’์ด ์žˆ๋‹ค๋ฉด ์ด๋ฏธ ํ•ด๋‹น ID๋Š” DB์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฑฐ๋ผ ์ด๋ฏธ ์žˆ๋Š” ๊ฐ’์ด๋ผ๊ณ  ์•Œ๋ ค์ฃผ๋Š”
Error๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.

๊ฐ’์ด ์—†๋‹ค๋ฉด ๋ณธ๊ฒฉ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ €์žฅ์„ ์œ„ํ•ด Repository์˜ saveEquipment()์— RequestDTO๋ฅผ
toEntity()๋ฅผ ์ด์šฉํ•˜์—ฌ Equipment Entity๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์ „๋‹ฌํ•ด ์ฃผ๋Š” ๋ถ€๋ถ„์ด์—์š”.

Repository ๋ถ€๋ถ„์—์„œ ๋ณด๊ฒ ์ง€๋งŒ, ํ•ด๋‹น ์—ฐ์‚ฐ์ด ์ฒ˜๋ฆฌ๋˜๋ฉด Euipement Entity๊ฐ€ ๋ฐ˜ํ™˜์ด ๋ผ์š”.
๊ทผ๋ฐ ๊ทธ ๊ฐ’์ด Null์ด๋ผ๋ฉด ์ €์žฅ์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— Error๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

Null์ด ์•„๋‹ˆ๋ผ๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๋œ ๊ฒƒ์ด๋‹ˆ HTTP Status Code 200๊ณผ
ํ•จ๊ป˜ ํ•ด๋‹น Entity์˜ ID๊ฐ’๋งŒ์„ ์ถ”์ถœํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ถ€๋ถ„์ด์—์š”.

src/app/equipment/service/equipment.service.ts


์œ„์—์„œ ์ด์•ผ๊ธฐ ํ–ˆ๋˜ ID๋ฅผ ๋จผ์ € ์ฐพ๋Š” Method(๋ฉ”์„œ๋“œ)๋Š” ์—ฌ๋Ÿฌ๋ฒˆ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ๋นผ๋†จ์–ด์š”.
์ด๋ ‡๊ฒŒ ID๊ฐ’์„ ๋ฐ›์•„ Repository์˜ findByEquipmentId()์—๊ฒŒ ์ „๋‹ฌํ•ด ์ฃผ๊ณ , ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์—ญํ• ์„ ํ•ด์ฃผ๋Š”๋ฐ,

์ด ๋•Œ๋„ Entity๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์–ด์š”.

 

 

        ๐Ÿ“ฆ Read - ๋ชฉ๋ก์กฐํšŒ

src/app/equipment/service/equipment.service.ts


์กฐํšŒ ๋ฐ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ ๊ทธ๋ฆฌ๊ณ , ์ •๋ ฌ์„ ์œ„ํ•ด ๋ฐ›์€ ์ธ์ž๊ฐ’์€ EquipmentSearchRequestDTO์˜ toDto()์— ์ „๋‹ฌ๋˜๊ณ ,
์ด๋ฅผ ํ†ตํ•ด ํ•ด๋‹น DTO ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜๋˜๊ฒŒ ํ•ด์ฃผ์—ˆ์–ด์š”.

๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น DTO๋ฅผ Repository ๋ฉ”์„œ๋“œ์— ์ „๋‹ฌํ•ด์„œ Query Builder๋ฅผ ์ด์šฉํ•œ ์—ฐ์‚ฐ์„ ์ฒ˜๋ฆฌํ•˜๊ณ ,
์กฐํšŒ๋œ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐฐ์—ด ์•ˆ์— Entity[]๊ณผ number๋ฅผ ๋ฐ›๋„๋กœ ๋ฐ›๋„๋ก ํ•˜์˜€์–ด์š”.

result ๋ฐฐ์—ด 0๋ฒˆ์งธ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒ๋œ ๊ฒฐ๊ณผ๊ฐ’์ด ๋“ค์–ด์žˆ๊ณ ,
1๋ฒˆ์งธ ๋ฐฐ์—ด์—๋Š” ํ•ด๋‹น Table์— ์กด์žฌํ•˜๋Š” ๊ฐ’๋“ค์˜ ๊ฐœ์ˆ˜๋ฅผ ๋‹ด๊ณ  ์žˆ์–ด์š”.

45 ~ 47๋ฒˆ์งธ ์ค„์€ ๊ทธ๋ ‡๊ฒŒ ์กฐํšŒ๋œ result[0]์˜ ๋ฐฐ์—ด ๊ธธ์ด๊ฐ€ 0์ด๋ผ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์กฐํšŒ๊ฐ€ ์•ˆ๋œ ๊ฒƒ์ด๋‹ˆ
๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋Š” Error๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.

๋ฐฐ์—ด์˜ ๊ธธ์ด๊ฐ€ 0์ด ์•„๋‹ˆ๋ผ๋ฉด ์กฐํšŒ๊ฐ€ ๋œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— Page ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒ๋œ ๊ฐ’๋“ค์˜ ๊ฐœ์ˆ˜๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ , ๋‘๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ํ•ด๋‹น Talble์˜ ์ด ์š”์†Œ ๊ฐœ์ˆ˜๋ฅผ
๊ทธ๋ฆฌ๊ณ , 3๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒ๋œ ๊ฐ’๋“ค์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ฐฐ์—ด์„ map()์„ ํ†ตํ•ด Entity๋ฅผ ResponseDTO๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐฐ์—ด๋กœ ๋‹ด๊ธฐ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

 

๐Ÿ’ก async์™€ await

async์™€ await์€ JavaScript ๋ฐ TypeScript์—์„œ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํ‚ค์›Œ๋“œ.

๐Ÿ“ async: ํ•จ์ˆ˜๊ฐ€ ํ•ญ์ƒ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ์˜๋ฏธ. ์ด๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜ ๋‚ด์—์„œ await๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ์ž‘์—… ์ˆ˜ํ–‰.
async ํ•จ์ˆ˜ ๋‚ด์—์„œ await๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ์ด ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ Promise ๋ฐ˜ํ™˜.

๐Ÿ“ await: async ํ•จ์ˆ˜ ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Promise๊ฐ€ ์ฒ˜๋ฆฌ(resolve) ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๊ณ , Promise๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋ฉด
๊ฒฐ๊ณผ ๊ฐ’ ๋ฐ˜ํ™˜. ์ด๋ฅผ ํ†ตํ•ด ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋™๊ธฐ์‹ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ. ์‰ฝ๊ฒŒ ๋งํ•ด ์ž‘์—… ๋„˜๊ธฐ์ง€ ๋ง๊ณ , ๋๋‚  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ–ˆ๋‹ค๊ฐ€ ๋‹ค์Œ ์ž‘์—…์„ ํ•˜๋ผ๋Š” ์˜๋ฏธ.

async์™€ await์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ณด๋‹ค ์„ ์–ธ์ ์ด๊ณ , ๋™๊ธฐ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , ์ฝœ๋ฐฑ์ด๋‚˜, .then()์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

 

Node.js ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ๋˜๊ธฐ : TypeScript + Node.js + Express + NestJS๋กœ ๋ฐฐ์šฐ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐฑ์—”๋“œ ์ž…๋ฌธ์ž

COUPANG

www.coupang.com

 

 




src/app/common/constant/page.ts


Page ๊ฐ์ฒด์˜ ์œ„์— ๊ฐ’๋“ค์ด ์ „๋‹ฌ๋˜๋ฉด ์ฒซ๋ฒˆ์งธ ์ธ์ž๊ฐ’๊ณผ ๋‘๋ฒˆ์งธ ์ธ์ž๊ฐ’์€ ๊ทธ๋Œ€๋กœ ๊ฐ๊ฐ์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ์ž…๋ ฅ ๋˜๋„๋ก ํ•ด ์ฃผ์—ˆ๊ณ ,

totalPage๋Š” perPageSize(ํ•œ ํŽ˜์ด์ง€ ๋‹น ํ‘œ์‹œํ•  ์š”์†Œ ๊ฐœ์ˆ˜)๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค Table์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ์š”์†Œ์˜ ๊ฐ’์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋‚˜์˜จ ์ˆ˜๋ฅผ Round Up(์˜ฌ๋ฆผ)ํ•˜์—ฌ ๊ณ„์‚ฐ๋œ ๊ฐ’์„ tempTotalPage์— ๋‹ด๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

๋งŒ์•ฝ totalCount๊ฐ€ 10์ด๊ณ , perPageSize๊ฐ€ 3์ด๋ผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋œ๋‹ต๋‹ˆ๋‹ค.

Math.ceil(10 / 3) = Math.ceil(3.333....) = 4

์œ„ ์˜ˆ์‹œ๋กœ๋Š” 4๊ฐœ์˜ Page๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๊ณ , Page ๋‹น 3๊ฐœ์˜ ํ•ญ๋ชฉ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋งˆ์ง€๋ง‰
Page์—๋Š” 1๊ฐœ์˜ ํ•ญ๋ชฉ์ด ์žˆ๊ฒŒ ๋  ๊ฒƒ์ด์—์š”.

๊ทธ๋Ÿฐ ๋’ค 13 ~ 17๋ฒˆ์งธ ์ค„์— ํ•ด๋‹น ๊ฐ’์ด 1๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜, ๊ฐ™์œผ๋ฉด tempTotalPage๋ฅผ totalPage ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ๋‹ด์•„์ฃผ๊ณ ,

์•„๋‹ˆ๋ผ๋ฉด 1์ด ๋‹ด๊ธฐ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

data๋ผ๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์—๋Š” ์–ด๋–ค ์ž๋ฃŒํ˜• ํƒ€์ž…์„ ๊ฐ–์€ ๋ฐฐ์—ด๋„ ๋‹ด๊ธธ ์ˆ˜ ์žˆ๊ฒŒ ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.




src/app/equipment/model/dto/request/equipment-search-request.dto.ts


๊ฒ€์ƒ‰์„ ์œ„ํ•œ ์š”์ฒญ DTO๋Š” PageRequestDto๋ฅผ ์ƒ์† ๋ฐ›๊ณ  ์žˆ์–ด์š”.

๋ฉค๋ฒ„ ๋ณ€์ˆ˜์ธ usedBy์™€ newOrUsed๋Š” ๋ฌธ์ž์—ด ๋˜๋Š” Null์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ •์˜ํ•ด ์ฃผ์—ˆ์–ด์š”.

๋‚˜๋จธ์ง€ ๊ฐ’๋“ค์€ ๋ถ€๋ชจ ํด๋ž˜์Šค PageRequestDto์—์„œ ์ƒ์†๋˜์—ˆ๊ฑฐ๋‚˜, ์ดˆ๊ธฐํ™”๊ฐ€ ๋˜์–ด ์žˆ์–ด์š”.

์ƒ์„ฑ์ž์—์„œ๋Š” ๋น„์–ด์žˆ๋Š” ์ƒ์„ฑ์ž๋ฅผ ์ •์˜ํ•ด ์ฃผ์—ˆ๋Š”๋ฐ,
๋ถ€๋ชจ ํด๋ž˜์Šค์ธ PageRequestDto์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์—ญํ• ๋งŒ ํ•˜๊ณ  ์žˆ์–ด์š”.

toDto()๋Š” Client์—์„œ ๊ฐ’์„ ๋ฐ›์„ ๋•Œ DTO ๊ฐ์ฒด์— ๋ฐ”๋กœ ๋ฐ›๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๊ฐ๊ฐ์˜ ์š”์†Œ๋“ค์„ ๋ฐ›๊ณ  ์žˆ๊ณ ,
์ด๋ฅผ DTO๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์–ด์š”.


src/app/common/constant/page.request.dto.ts


PageRequestDto๋Š” Abstract Class(์ถ”์ƒ ํด๋ž˜์Šค)๋กœ ๋˜์–ด ์žˆ์–ด์š”.
์ถ”์ƒ ํด๋ž˜์Šค๋กœ ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ง์ ‘ ์ธ์Šคํ„ด์Šค์™€ ํ•  ์ˆ˜ ์—†๊ณ ,
์ด ํด๋ž˜์Šค๋ฅผ ์ƒ์† ๋ฐ›๋Š” ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„์„ ์™„์„ฑํ•ด ์ฃผ์–ด์•ผ ํ•ด์š”.

์—ฌ๊ธฐ์„œ pageNumber (ํ˜„์žฌ ์œ„์น˜ํ•œ Page ๋ฒˆํ˜ธ), perPageSize(ํ•œ ํŽ˜์ด์ง€์— ์ถœ๋ ฅํ•  ์š”์†Œ ๊ฐœ์ˆ˜),
orderBy(์ •๋ ฌ)์„ ์ •์˜ํ•ด ์ฃผ์—ˆ์–ด์š”. 

 

 

 

 

        ๐Ÿ“ฆ Read - ์ƒ์„ธ์กฐํšŒ

src/app/equipment/service/equipment.service.ts


์œ„ ์ฝ”๋“œ๋Š” ์ตœ์ดˆ ์กฐํšŒํ•  ID๊ฐ’์ด Null์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ ,
Null์ด ์•„๋‹ˆ๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ํ•ด๋‹น ID๋ฅผ ์กฐํšŒํ•œ ๋’ค Entity๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค 64 ~ 66๋ฒˆ์งธ ์ค„์€ ์กฐํšŒ๋œ Entity๋ฅผ ๋‹ค์‹œ Null์ธ์ง€ ํ™•์ธํ•˜๊ณ , Null์ด ์•„๋‹ˆ๋ฉด ์ •์ƒ ์กฐํšŒ๋ฅผ ์•Œ๋ ค์ค€ ๋’ค Entity๋ฅผ ResponseDTO๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋ฐ˜ํ™˜ํ•ด ์ฃผ๊ณ  ์žˆ์–ด์š”.
ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ Null์ด๋ผ๋ฉด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ ๋ชป ์ฐพ์€ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋‚ด์šฉ์„ 68๋ฒˆ์งธ ์ค„์„ ์ด์šฉํ•ด์„œ ๋ฐ˜ํ™˜ํ•ด์ฃผ๊ณ ,

71๋ฒˆ์งธ ์ค„์€ 61๋ฒˆ์งธ ์ค„์ด Null์ด ์˜€๋‹ค๋ฉด ID๋ฅผ ์ž˜ ๋ชป ์ „๋‹ฌํ•ด ์ค€ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋‚ด์šฉ์— ๋Œ€ํ•ด ๋ฐ˜ํ™˜ํ•ด ์ฃผ๊ณ  ์žˆ์–ด์š”.

62๋ฒˆ์งธ ์ค„์—์„œ ํ˜ธ์ถœํ•˜๋Š” findByEquipmentId()๋Š” ์•„๋ž˜ ๋ฉ”์„œ๋“œ์—์š”.


src/app/equipment/service/equipment.service.ts


์œ„์—์„œ ์ €์žฅ ๋กœ์ง์„ ์ด์•ผ๊ธฐํ•  ๋•Œ ๊ณตํ†ต์œผ๋กœ ์“ด๋‹ค๋Š” ๋ถ€๋ถ„์ด ์ด๋Ÿฐ ๋ถ€๋ถ„์ด๋ผ ์ด๋ ‡๊ฒŒ ๋”ฐ๋กœ ๋นผ๋…ผ ๊ฒƒ์ด์—์š”.

 

 

        ๐Ÿ“ฆ Update

src/app/equipment/service/equipment.service.ts


76 ~ 78๋ฒˆ์งธ ์ค„์—์„œ ID๊ฐ’์ด Null์ด ์•„๋‹Œ์ง€ ํ™•์ธํ•˜๊ณ  ์žˆ์–ด์š”.
Null์ด๋ผ๋ฉด ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ฒ ๋‹ค๋Š”๊ฑด์ง€ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— 77๋ฒˆ์งธ ์ค„์— ํ•ด๋‹น ๋‚ด์šฉ์— ๋Œ€ํ•ด ๋ฐ˜ํ™˜ํ•ด์ฃผ๊ณ  ์žˆ์–ด์š”.

Null์ด ์•„๋‹ˆ๋ผ๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํ•ด๋‹น ID๋ฅผ ์กฐํšŒํ•œ ๋’ค ๋ฐ˜ํ™˜ ๋ฐ›์€ Entity๋ฅผ 82๋ฒˆ์งธ ์ค„์—์„œ Null์ธ์ง€ ํ™•์ธํ•˜๊ณ  ์žˆ์–ด์š”.
Null์ด๋ผ๋ฉด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ํ•ด ์ค€๋‹ต๋‹ˆ๋‹ค.

Null์ด ์•„๋‹ˆ์˜€๋‹ค๋ฉด ์ˆ˜์ • ๋Œ€์ƒ์„ ์ฐพ์•˜๊ธฐ ๋•Œ๋ฌธ์— updateEquipment()๋ผ๋Š” ๋ฉ”์„œ๋“œ์— ํ•ด๋‹น ID๊ฐ’๊ณผ ์ˆ˜์ •ํ•  ๋‚ด์šฉ์„ ๋‹ด์€ RequestDto๋ฅผ Entity๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ „๋‹ฌํ•ด ์ฃผ๊ณ  ์žˆ์–ด์š”.

๊ทธ๋ ‡๊ฒŒ ํ•ด์„œ ์ˆ˜์ •์ด ๋๋‚˜๋ฉด ์ •์ƒ ์ฒ˜๋ฆฌ ๋˜์—ˆ๋‹ค๋Š” ๋‚ด์šฉ๊ณผ ํ•จ๊ป˜ ์ˆ˜์ • ๋˜์–ด ๋ฐ˜ํ™˜๋œ Entity์˜ ID๊ฐ’์„ ์ „๋‹ฌํ•ด ์ฃผ๊ณ  ์žˆ์–ด์š”.






        ๐Ÿ“ฆ Delete

src/app/equipment/service/equipment.service.ts


95๋ฒˆ์งธ ์ค„์—์„œ ID๊ฐ’์ด Null์ธ์ง€ ํ™•์ธํ•˜๊ณ , Null์ด ์•„๋‹ˆ๋ผ๋ฉด ์‚ญ์ œ ๋Œ€์ƒ Entity๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ID๊ฐ’์„ ์กฐํšŒํ•œ ๋’ค ๋ฐ˜ํ™˜๋œ Entity ๊ฐ’์œผ๋กœ 98๋ฒˆ์งธ ์ค„์—์„œ Null ํ™•์ธ์„ ๋‹ค์‹œ ํ•ด ์ฃผ์—ˆ์–ด์š”.
๊ทธ๋ž˜์„œ Null์ด๋ผ๋ฉด ์‚ญ์ œ ๋Œ€์ƒ Entity๊ฐ€ ์—†๋‹ค๋Š” ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ํ•ด ์ค๋‹ˆ๋‹ค.

Null์ด ์•„๋‹ˆ๋ฉด ์‚ญ์ œ ๋Œ€์ƒ ๊ฐœ์ฒด๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ Delete Query๋ฅผ ๋‚ ๋ ค ํ•ด๋‹น ID๊ฐ’์„ ๊ฐ€์ง„ ๊ฐœ์ฒด๋ฅผ ์‚ญ์ œํ•˜๊ณ , ์‚ญ์ œ๋œ Result๊ฐ’(Entity ๋ฐ˜ํ™˜ ์•„๋‹˜)์„ 104๋ฒˆ์งธ ์ค„์—์„œ Null์ธ์ง€ ํ™•์ธํ•˜์—ฌ
Null์ด๋ฉด ์‚ญ์ œ๊ฐ€ ์‹คํŒจํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•˜๊ณ , ํ•ด๋‹น ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ํ•ด ์ฃผ์—ˆ์–ด์š”.

Null์ด ์•„๋‹ˆ๋ฉด ์ •์ƒ ์‚ญ์ œ ๋œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋‚ด์šฉ๊ณผ ํ•จ๊ป˜ ID๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด ์ฃผ๋Š”๋ฐ,
์ด ๋•Œ๋Š” Client๊ฐ€ ์ „๋‹ฌํ•œ ID๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

 

 

 

 

 

    ๐Ÿ”ฝ Equipment - Repository

src/app/equipment/repository/equipment.repository.ts


์œ„์—์„œ๋„ ์ด์•ผ๊ธฐํ–ˆ๋“ฏ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ณ„์ธต์ธ Repository ์—ญ์‹œ @Injectable()์„ ๋„ฃ์–ด DI๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ์—ˆ์–ด์š”.

๊ทธ๋ฆฌ๊ณ , ์ƒ์„ฑ์ž๋ฅผ ์ด์šฉํ•ด์„œ Repository<>๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”.

@InjectRepository()๋Š” TypeORM๊ณผ ์‚ฌ์šฉ๋˜๋Š” Decorator๋กœ Nest.js์—์„œ Repository๋ฅผ ์ฃผ์ž…๋ฐ›๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ด์š”.

Nest.js๋Š” Spring Boot์™€ ๋น„์Šทํ•˜๊ฒŒ ์˜์กด์„ฑ ์ฃผ์ž…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” Framework(ํ”„๋ ˆ์ž„์›Œํฌ)์ด๋ฉฐ,
@InjectRepository๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ TypeORM์ด ๊ด€๋ฆฌํ•˜๋Š” Entity์— ๋Œ€ํ•œ Repository๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค€๋‹ต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ @InjectRepository(EquipmentEntity)๋Š” EquipmentEntity๋ผ๋Š”
TypeORM Entity์— ๋Œ€ํ•œ Repository๋ฅผ ์ฃผ์ž…ํ•˜๊ฒ ๋‹ค๊ณ  ์ •์˜ํ•ด์ค€ ๊ฒƒ์ด์—์š”.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค์—์„œ TypeORM์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์š”.

node_modules/typeorm/repository/Repository.d.ts



equipmentRepository ๋ณ€์ˆ˜๋Š” Repository<Entity> ์ž๋ฃŒํ˜• Type์„ ๊ฐ–๊ณ  ์žˆ๋Š”๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”.
ํ•ด๋‹น ๊ฐ์ฒด๋Š” TypeORM์—์„œ ์ œ๊ณตํ•˜๋Š” Repository ๊ฐ์ฒด์ธ๋ฐ,
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋“ค์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์–ด์š”. 

ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด Generiecs(์ œ๋„ค๋ฆญ์Šค) ๋ฌธ๋ฒ•์„ ํ™œ์šฉํ•˜์—ฌ ์„ ์–ธ๋˜์–ด ์žˆ๋Š”๋ฐ,
TypeScript์—์„œ export Keyword๋Š” ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋„๋ก ๋‚ด๋ณด๋‚ด๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์—์š”.
declare๋Š” Compiler์—๊ฒŒ ํ•ด๋‹น Simbol(ํด๋ž˜์Šค, ํ•จ์ˆ˜, ๋ณ€์ˆ˜ ๋“ฑ)์ด ์ด๋ฏธ ์–ด๋””์„œ ์„ ์–ธ๋˜์—ˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์ด์—์š”.

Eneity extends ObjectLiteral์˜ Entity๋Š” ํ•ด๋‹น Repository์—์„œ ๊ด€๋ฆฌํ•˜๋Š” Entity Type์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€๋ถ„์ด์—์š”.
extends ObjectLiteral์€ Entity๊ฐ€ ObjectLiteral์ด๋ผ๋Š” Type์„ ํ™•์žฅ(์ƒ์†)ํ•œ๋‹ค๋Š” ์˜๋ฏธ์—์š”.

ObjectLiteral์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์–ด๋–ค ๊ฐ์ฒด์˜ ๊ตฌ์กฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” TypeScript์˜ Type์ด์—์š”.
์ด๋Š” Key-Value ์Œ์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•ด์š”.


 

 

        ๐Ÿ“ฆ Create

src/app/equipment/repository/equipment.repository.ts

 

node_modules/typeorm/repository/Repository.d.ts


์ €์žฅ์€ ์œ„์™€ ๊ฐ™์ด save()๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ €์žฅ์„ ํ•ด์ฃผ๊ณ  ์žˆ์–ด์š”.
Entity๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅ ๋’ค ์ €์žฅ ๋œ ๊ฐ’์— ๋Œ€ํ•œ ๋‚ด์šฉ์„
Promise ๊ฐ์ฒด์— ๊ฐ์‹ธ์ง„ Entity ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด์š”.

 

src/app/equipment/repository/equipment.repository.ts

 

node_modules/typeorm/repository/Repository.d.ts



ID ์กฐํšŒ๋ฅผ ์œ„ํ•œ Repository ๋ฉ”์„œ๋“œ๋Š” ์œ„์™€ ๊ฐ™์•„์š”.
์ด๋ ‡๊ฒŒ ๊ฐ์ฒด๋ฅผ ์ธ์ž๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฐ, ๊ฐ์ฒด์˜ ์ด๋ฆ„์€ where๋กœํ•˜๊ณ , ๊ฐ’์„ ์กฐํšŒํ•  ID๋กœ ๋„ฃ์–ด ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋ฉด
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ํ•ด๋‹น ID๋ฅผ ์กฐํšŒํ•˜์—ฌ ์กฐํšŒ๋œ ๊ฐ’์„ Entity๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์–ด์š”.

์ด ๋ถ€๋ถ„์€ ์ƒ์„ธ ์กฐํšŒ๋•Œ๋„ ์‚ฌ์šฉ๋˜๊ณ , Update, Delete ๋•Œ๋„ ์‚ฌ์šฉ๋จ์„ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.








        ๐Ÿ“ฆ Read - ๋ชฉ๋ก์กฐํšŒ

src/app/equipment/repository/equipment.repository.ts

๋ฐ˜์‘ํ˜•


์œ„์˜ ์ฝ”๋“œ๋„ ๋ถ„์„ํ•ด ๋ณผ๊ฒŒ์š”.

์ตœ์ดˆ 17๋ฒˆ์งธ ์ค„์— QueryBuilder๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
createQueryBuilder()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ equipment ๋ผ๋Š” Alias(๋ณ„์นญ)์„ ๊ฐ€์ง„
EquipmentEntity์— ๋Œ€ํ•œ QueryBuilder๋ฅผ ๋งŒ๋“ค์—ˆ์–ด์š”.

limit() ๊ณผ offset()์„ ์‚ฌ์šฉํ•˜์—ฌ Pagination ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ์ฃผ์—ˆ์–ด์š”.
์ฐธ๊ณ ๋กœ Join ๋“ฑ์„ ์ด์šฉํ•  ๋•, take()์™€ skip()์„ ์‚ฌ์šฉํ•ด ์ฃผ์–ด์•ผ ํ•ด์š”.

21 ~ 27๋ฒˆ์งธ์ค„ ๊นŒ์ง€๋Š” ์กฐ๊ฑด์ ˆ ์ฆ‰, ๊ฒ€์ƒ‰ ์กฐ๊ฑด์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„์ธ๋ฐ, usedBy์™€ newOrUsed ์†์„ฑ์ด ์กด์žฌํ•˜๋Š”์ง€๋ฅผ ๋จผ์ € ํ™•์ธํ•˜๊ณ , ์กด์žฌํ•œ๋‹ค๋ฉด ํ•ด๋‹น ์กฐ๊ฑด์„ andWhere()๋ฅผ ์ด์šฉํ•ด์„œ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋ฆฌ๊ณ , 29 ~ 30๋ฒˆ์งธ ์ค„์€ RequestDTO์— orderBy๊ฐ’์ด true์ด๋ฉด ๋‚ด๋ฆผ์ฐจ์ˆœ์ด ๋  ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.
๊ธฐ๋ณธ๊ฐ’์€ ์˜ค๋ฆ„์ฐจ์ˆœ์ด๋‹ˆ true๊ฐ€ ์•„๋‹ˆ๋ฉด ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ฒ˜๋ฆฌ๋  ๊ฑฐ์—์š”.

๊ทธ๋Ÿฐ ๋’ค 33๋ฒˆ์งธ ์ค„์— getManaAndCount()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ SQL Query๋ฅผ ์‹คํ–‰ํ•˜๊ณ ,
๊ฒฐ๊ณผ๋กœ ํ•˜๋‚˜์˜ ๋ฐฐ์—ด ์•ˆ์˜ 0๋ฒˆ์งธ ๋ฐฐ์—ด์—๋Š” EquipmentEntity[]
๊ทธ๋ฆฌ๊ณ , 1๋ฒˆ์งธ ๋ฐฐ์—ด์—๋Š” Table์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ์š”์†Œ ๊ฐœ์ˆ˜ ๊ฐ’์„ ๋‹ด์€ number๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

์ด๋ ‡๊ฒŒ ๋™์  ์ฟผ๋ฆฌ๊ฐ€ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์ค€ ๊ฒƒ์ด์—์š”.





        ๐Ÿ“ฆ Update

node_modules/typeorm/repository/Repository.d.ts


TypeORM์˜ update()๋ฅผ ๋ณด๋ฉด Updateํ•  ๋Œ€์ƒ Entity๋ฅผ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์ค€ ๊ฐ’์„ ์ „๋‹ฌํ•ด ์ค˜์•ผํ•˜๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์–ด์š”.

์ด ๋•Œ๋Š” string, number, Date, ObjectId ๋“ฑ ์—ฌ๋Ÿฌ ํ˜•์‹์„ ์ด์šฉํ•ด์„œ ๊ธฐ์ค€์„ ์žก์„ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ ธ ์žˆ๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์–ด์š”.
๊ทธ๋ฆฌ๊ณ , findOptionsWhere<Entity> ํ˜•์‹์œผ๋กœ๋„ ๊ธฐ์ค€์„ ์žก์„ ์ˆ˜ ์žˆ๊ณ , Update ๋Œ€์ƒ Entity๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์–ด์š”.

partialEntity๋Š” Updateํ•  ๋‚ด์šฉ์ด ๋‹ด๊ธด Entity๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š” ๋ถ€๋ถ„์ด์—์š”.
QueryDeepPartialEntity<Entity> ํ˜•์‹์€ Entity์˜ ์ผ๋ถ€ ์†์„ฑ๋งŒ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด์—์š”.

 

 

src/app/equipment/repository/equipment.repository.ts


์ฆ‰, ์œ„์˜ ๋ฉ”์„œ๋“œ๋Š” TypeORM์˜ update()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๊ณ , ID๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ Entity๋ฅผ ์„ ํƒํ•˜๋Š” ๊ธฐ์ค€์„ ์ œ์‹œํ–ˆ๊ณ ,
์ˆ˜์ • ๊ฐ’์ด ๋‹ด๊ธด Entity๋ฅผ ์ „๋‹ฌํ•จ์œผ๋กœ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๊ฐ’์„ ์ „๋‹ฌํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.

์ฐธ๊ณ ๋กœ Update๋ฅผ ํ•  ๋•Œ, save()๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋˜๊ธฐ๋Š” ํ•˜๋Š”๋ฐ,

update()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ด€๊ณ„ ๋ฐ ๊ธฐํƒ€ ์ž‘์—…์ด ํฌํ•จ๋œ Cascade๊ฐ€ ์—†๋Š” ์›์‹œ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋ผ์š”.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋น ๋ฅด๊ณ , ํšจ์œจ์ ์ธ Update Query๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.
๋‹จ, Entity๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ํ™•์ธํ•ด ์ฃผ์–ด์•ผ ํ•ด์š”.






        ๐Ÿ“ฆ Delete

node_modules/typeorm/repository/Repository.d.ts


TypeORM delete()๋Š” deleteQueryBuilder๋ฅผ ํ†ตํ•ด ์‹คํ–‰๋˜๋ฉฐ, ์‚ญ์ œ ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๋ฉด DeleteResult๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ผ์š”.


node_modules/typeorm/query-builder/result/DeleteResult.d.ts

 

Node. js ๊ต๊ณผ์„œ

COUPANG

www.coupang.com


์œ„ ๋‚ด์šฉ์ด DeleteResult ํด๋ž˜์Šค์ธ๋ฐ, 10๋ฒˆ์งธ ์ค„์€ ์‹คํ–‰๋œ SQL Query์˜ ์›์‹œ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์—์š”.

15๋ฒˆ์งธ ์ค„์€ Query์— ์˜ํ•ด ์˜ํ–ฅ๋ฐ›์€ Row(ํ–‰) ๋˜๋Š” Document(๋ฌธ์„œ)์˜ ์ˆ˜๋ฅผ ๋‹ด๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์—์š”.
์ด ๋ณ€์ˆ˜๋Š” DELETE Query์— ์˜ํ•ด ์˜ํ–ฅ์„ ๋ฐ›์€ Entity ๊ฐœ์ˆ˜๋ฅผ ๋‹ด๊ณ  ์žˆ๊ณ ,
์ผ๋ถ€ SQL Driver์—์„œ๋Š” ์ง€์›์ด ์•ˆ๋  ์ˆ˜๋„ ์žˆ์–ด์š”. ๊ทธ๋ž˜์„œ Null ๊ฐ’์ด ๋‹ด๊ฒจ ์žˆ์„ ์ˆ˜๋„ ์žˆ์–ด์š”.

6๋ฒˆ์งธ ์ค„์€ Static(์ •์ ) ๋ฉ”์„œ๋“œ๋กœ QueryResult ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„ DeleteResult ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์š”.


src/app/equipment/repository/equipment.repository.ts


๊ฒฐ๊ตญ Repository์— ์žˆ๋Š” delete()๋Š” ์œ„ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ธ๋ฐ, ID๊ฐ’์„ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ด์ฃผ๊ฒŒ ๋˜๋ฉด
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์‚ญ์ œ Query๋ฅผ ๋‚ ๋ฆฌ๊ฒŒ ๋˜๊ณ , ์‚ญ์ œ ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๋ฉด DeleteResult ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋  ๊ฒƒ์ด๊ณ ,
affected ์†์„ฑ์„ ํ†ตํ•ด ์˜ํ–ฅ ๋ฐ›์€ ํ–‰์˜ ์ˆ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์—์š”.

ํ•˜์ง€๋งŒ, ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋  ๊ฒƒ์ด์—์š”.

์ฐธ๊ณ ๋กœ ๋ฐ˜ํ™˜๋˜๋Š” ๊ตฌ์ฒด์  ์˜ˆ์™ธ๋Š” ์‚ฌ์šฉ์ค‘์ธ ORM Driver์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์–ด์š”.
๋Œ€๋ถ€๋ถ„ ์‹คํŒจํ•œ ๊ฒฝ์šฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ์˜ˆ์™ธ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ์ฒ˜๋ฆฌ๋œ๋‹ต๋‹ˆ๋‹ค.






    ๐Ÿ”ฝ Equipment - Module

Nest.js์—์„œ Module(๋ชจ๋“ˆ)์€ Application์„ ๊ตฌ์„ฑํ•˜๋Š” ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ ์ค‘ ํ•˜๋‚˜์—์š”.
๊ฐœ์ธ์ ์œผ๋กœ Spring Boot์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ, ์ด๋Ÿฐ ๋ถ€๋ถ„์„ ๋ช…์‹œํ•ด์ค˜์•ผ ํ•œ๋‹ค๋Š”๊ฒŒ ๋ถˆํŽธํ•จ์œผ๋กœ ๋‹ค๊ฐ€์™”์–ด์š”.

๋ชจ๋“ˆ์€ ํŠน์ • ๊ธฐ๋Šฅ์ด๋‚˜, ์˜์—ญ์— ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ๊ตฌ์กฐํ™”ํ•˜๊ณ , Encapsulation(์บก์Šํ™”)ํ•˜๋ฉฐ, ์˜์กด์„ฑ ์ฃผ์ž…๋ฅผ ํ†ตํ•ด ๋ชจ๋“ˆ ๊ฐ„ ์„œ๋น„์Šค๋‚˜, ๊ธฐ๋Šฅ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ๋Š” ๋ถ€๋ถ„์ด์—์š”.

๋ชจ๋“ˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฃผ์š” ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”.

์ฃผ์š” ํŠน์ง• ์ƒ์„ธ ๋‚ด์šฉ
@Module @Module๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Module ์ •์˜.
@Module์€ Module์˜ Metadata๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, Nest.js์—๊ฒŒ ํ•ด๋‹น Class๊ฐ€ Module์ž„์„ ์•Œ๋ ค์คŒ.
imports Module์€ ๋‹ค๋ฅธ Module์„ Importํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, imports ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„์žฌ Module์ด ์˜์กดํ•˜๋Š” ๋‹ค๋ฅธ Module ์„ ์–ธ.
exprots ํŠน์ • Module์—์„œ ์ •์˜ํ•œ Service, Component ๋“ฑ์„ ๋‹ค๋ฅธ Module์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‚ด๋ณด๋‚ด๊ณ ์ž ํ•  ๋•Œ, exports ์†์„ฑ ์‚ฌ์šฉ.
providers ๋ชจ๋“ˆ์€ Service, Repository, Factory, Provider ๋“ฑ์˜ ์ œ๊ณต์ž๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ œ๊ณต์ž๋Š” ์ฃผ๋กœ ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด ๋‹ค๋ฅธ ๋ถ€๋ถ„์—์„œ ์‚ฌ์šฉ.


Nest.js์˜ ๋ชจ๋“ˆ System(์‹œ์Šคํ…œ)์€ Application์„ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ ๋ชจ๋“ˆ๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ ๋ชจ๋“ˆ์ด ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœ๋˜๊ณ , Test ๋˜๋ฉฐ,
ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์žฌ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ์นœ๊ตฌ์—์š”.
์ด๋กœ์จ Application ์œ ์ง€๋ณด๊ตฌ์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ํ–ฅ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๊ณ ํ•ด์š”.

src/app/equipment/module/equipment-module.ts


์œ„ ๋ชจ๋“ˆ์€ EquipmentModule์ด๋ผ๋Š” Nest.js ๋ชจ๋“ˆ์„ ์ •์˜ํ•˜๋Š” ์ฝ”๋“œ์—์š”.
9๋ฒˆ์งธ ์ค„์„ ํ†ตํ•ด TypeORM์„ ์‚ฌ์šฉํ•˜์—ฌ EquipmentEntity๋ฅผ ์ด ๋ชจ๋“ˆ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

10๋ฒˆ์งธ ์ค„์—์„œ๋Š” ๋ชจ๋“ˆ์—์„œ ์‚ฌ์šฉํ•  Provider(Service, Repository, Resolver) ๋“ฑ์„ ์ •์˜ํ•ด ์ฃผ์—ˆ์–ด์š”.
์ฆ‰, EquipmentResolver, EquipmentService, EquipmentRepository๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๊ณ  ์ •์˜ํ•œ ๋ถ€๋ถ„์ด์—์š”.


src/app.module.ts


์œ„ ์ฝ”๋“œ๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ์„ ์ค‘์•™ ์ง‘์ค‘์‹์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ณณ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ผ์š”.

13๋ฒˆ์งธ ์ค„์„ ํ†ตํ•ด ํ™˜๊ฒฝ ์„ค์ •์„ Load ํ•˜๊ธฐ ์œ„ํ•œ ConfigModule์„ ์„ค์ •ํ•ด ์ฃผ๋Š”๋ฐ, CONFIG_VALIDATOR๋Š” ํ™˜๊ฒฝ ์„ค์ •์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด์—์š”.

src/common/config/config.validator.ts

 

src/app.module.ts


14 ~ 16๋ฒˆ์งธ ์ค„์€ TypeORM์„ Application์— ์„ค์ •ํ•˜๋Š” ๋ถ€๋ถ„์ธ๋ฐ,
SqliteConfigProvider ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ •์„ ๊ตฌ์„ฑํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.

18 ~ 23๋ฒˆ์งธ ์ค„๊นŒ์ง€๋Š” GraphQL ์„ค์ • ๋ถ€๋ถ„์ธ๋ฐ, ์—ฌ๊ธฐ์„œ Apollo Server๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ •์˜ํ•ด ์ฃผ๊ณ , ApolloDriverConfig Option์„ ์ œ๊ณตํ•ด ์ฃผ์—ˆ์–ด์š”.

24๋ฒˆ์งธ ์ค„์€ ์œ„์—์„œ ์ •์˜ํ–ˆ๋˜ EquipmentModule์„ Importํ•˜์—ฌ
Application์— ํŠน์ • ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •์˜ํ•œ ๊ฒƒ์ด์—์š”.

์ด๋ ‡๊ฒŒ ๋ชจ๋“ˆ์„ ๊ณ„์ธต์ ์œผ๋กœ ๊ตฌ์„ฑํ•จ์œผ๋กœ ๊ฐ ๋ชจ๋“ˆ์ด ํŠน์ • ๊ธฐ๋Šฅ์ด๋‚˜, ์˜์—ญ์„ ์ฑ…์ž„์ง€๋„๋ก ํ•˜๊ณ ,
Application ์ „์ฒด๋ฅผ ๋ชจ๋“ˆ๋กœ ๊ตฌ์„ฑํ•จ์œผ๋กœ์จ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด Nest.js์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜์—์š”.



 

 

 

GraphQL๊ณผ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋กœ ๊ฐœ๋ฐœํ•˜๋Š” ์›น ์„œ๋น„์Šค:์„ค๊ณ„๋ถ€ํ„ฐ ๊ฐœ๋ฐœ·๋ฐฐํฌ๊นŒ์ง€ ๋”ฐ๋ผ ํ•˜๋ฉฐ ์™„์„ฑํ•˜๋Š” ์›น ํ’€

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 

 

 

๐Ÿง ์ฐธ๊ณ  ์ž๋ฃŒ

 

NestJS + typeORM + GraphQL ์ ์šฉํ•˜๊ธฐ

์‹œ์ž‘ํ•˜๊ธฐ

arta1069.medium.com

 

 

 

 

์นด์นด์˜คํŽ˜์ด | ๋งˆ์Œ ๋†“๊ณ  ๊ธˆ์œตํ•˜๋‹ค

์—ฌ๊ธฐ๋ฅผ ๋ˆŒ๋Ÿฌ ๋งํฌ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

qr.kakaopay.com

 

 

 

728x90
๋ฐ˜์‘ํ˜•