Back-End ์ž‘์—…์‹ค/Spring Framework

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

์ฃผ๋‹ˆ์“ฐ๐Ÿง‘‍๐Ÿ’ป 2023. 11. 21. 15:36
728x90
๋ฐ˜์‘ํ˜•

 

 

 

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

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

qr.kakaopay.com

 

 

 

 

์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ:์Šคํ”„๋ง ๋ฐ์ดํ„ฐ ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๋กœ ๋ฐฐ์šฐ๋Š” ์ „์ž์ •๋ถ€ ํ‘œ์ค€ ๋ฐ์ดํ„ฐ๋ฒ ์ด

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 ์•„ํ™‰๋ฒˆ์งธ ์ด์•ผ๊ธฐ

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

        ๐Ÿ“ฆ ๊ฐœ์š”

์ด ์ „๊นŒ์ง€ ๊ธ€์€ ๋ชจ๋‘ ์–„์ฝ”๋‹˜์˜ ์ธํ”„๋Ÿฐ ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉด์„œ ์ •๋ฆฌํ•˜๊ณ , ๋˜ ์ถ”๊ฐ€์ ์œผ๋กœ ์ฃผ๋‹ˆ๊ฐ€ ๊ฒฝํ—˜ํ•œ ๋‚ด์šฉ์ด๋‚˜, ์•„๋Š” ๊ฒƒ์„ ๋ง๋ถ™ํ˜€์„œ ์ •๋ฆฌํ•˜๋Š” ๋‚ด์šฉ์ด์˜€์–ด์š”.

ํ•˜์ง€๋งŒ, ๊ฐ•์˜์— ์‚ฌ์šฉ๋˜๋Š” ์‹ค์Šต ํ™˜๊ฒฝ์€ JavaScript์™€ Node.js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” csv File์„ ์ด์šฉํ•œ Mock Database(๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ •๋ง ๊ฐœ๋…๋งŒ ์ตํžˆ๋Š” ์‹ค์Šต์ด์˜€๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ์‹ค์Šต๊ณผ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณด๋ ค๊ณ  ํ•ด์š”.

์‹ค์Šต์€ Java์™€ Spring Boot ํ™˜๊ฒฝ๊ณผ TypeScript์™€ Nest.js๋ฅผ ์ด์šฉํ•ด์„œ ๊ตฌ์„ฑํ•ด ๋ณด๊ณ  ์‹ค์Šตํ•ด ๋ณด๋ ค๊ณ  ํ•ด์š”. 

 

 

 

 

 

 

    ๐Ÿ”ฝ  ํ™˜๊ฒฝ ๊ตฌ์„ฑ

        ๐Ÿ“ฆ Java + Spring Boot (์žํ”„๋ง)

์žํ”„๋ง์—์„œ๋Š” Spring for GraphQL์„ ์‚ฌ์šฉํ•ด ๋ณด๋ ค๊ณ  ํ•ด์š”.


๐Ÿ” graphql-java / graphql-java-spring
๐Ÿ” graphql-java-kickstart / graphql-spring-boot
๐Ÿ” Netflix / dgs-framwork

์Šคํ”„๋ง ์ง„์˜์—์„œ๋Š” ์œ„์™€ ๊ฐ™์ด GraphQL์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•œ 3๊ฐ€์ง€ ๋Œ€ํ‘œ์  Library(๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ) / ํ”„๋ ˆ์ž„์›Œํฌ(framwork)๊ฐ€ ์ค€๋น„ ๋˜์–ด ์žˆ๊ณ , ์ด ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜์—ฌ ์Šคํ”„๋ง ์ธก์—์„œ GraphQL์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•œ ๊ฒƒ์œผ๋กœ ๋ณด์—ฌ์š”.

๋ฟŒ๋ฆฌ๊ฐ€ ๋˜๋Š” ํ”„๋กœ์ ํŠธ๋Š” graphql-java / graphql-java-spring ์ด ํ”„๋กœ์ ํŠธ๋กœ ๋ชจ๋“  ํ”„๋กœ์ ํŠธ๊ฐ€ ์ด๊ฑธ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐœ๋ฐœ ๋˜์—ˆ๋‹ค๊ณ  ํ•ด์š”. ๋˜ํ•œ, Spring for GraphQL์€ ๊ณต์‹์ ์œผ๋กœ graphql-java์˜ ํ›„์† ํ”„๋กœ์ ํŠธ๋ผ๊ณ  ์†Œ๊ฐœํ•˜๊ณ  ์žˆ์–ด์š”.

์œ„์— ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๋“ค์„ ์ด์šฉํ•˜์—ฌ GraphQL์„ ๊ฐœ๋ฐœํ•˜๋ฉด ์ด ์ „๊นŒ์ง€ ๊ณต๋ถ€ํ–ˆ๋“ฏ์ด Resolver๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ , ๋ณ„๋„์˜ ์„ค์ • ๋“ฑ์„ ํ•ด์ฃผ์–ด์•ผ ํ–ˆ์ง€๋งŒ, Spring for GraphQL์€ graphql-java์˜ ๋‹จ์ˆœ ํ›„์† ํ”„๋กœ์ ํŠธ ๋ฟ ์•„๋‹ˆ๋ผ, graphql-java ๊ฐœ๋ฐœํŒ€์ด ๊ฐœ๋ฐœ์„ ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ์Šคํ”„๋ง ์ธก์—์„œ ์ถ”๊ตฌํ•˜๋Š” ๋ฐฉํ–ฅ๋‹ต๊ฒŒ ์ถ”๊ฐ€ ์ฝ”๋“œ ์—†์ด MVC ๊ฐœ๋ฐœํ•˜๋“ฏ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด ๋‘์—ˆ์–ด์š”.



        ๐Ÿ“ฆ ์‹ค์Šต ํ™˜๊ฒฝ

๐Ÿ” JDK 11
๐Ÿ” Spring Boot 2.7.17 (Spring for GraphQL์€ Spring Boot 2.7.0 ์ด์ƒ ์ง€์›)
๐Ÿ” Embedded H2 DBMS(In-Memory)
๐Ÿ” JPA & QueryDsl
๐Ÿ” InteliJ (2023.2.5 Ultimate)

 

 

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


์ตœ์ดˆ ์ธํ…”๋ฆฌ์ œ์ด์—์„œ ์œ„์™€ ๊ฐ™์ด ํ”„๋กœ์ ํŠธ ํƒญ์—์„œ ์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ˆŒ๋Ÿฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์ค„๊ฒŒ์š”.


๊ทธ๋ฆฌ๊ณ  Spring Initializr์—์„œ ์œ„์™€ ๊ฐ™์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.
์ฐธ๊ณ ๋กœ Comunity ๋ฒ„์ „์„ ์“ฐ์‹œ๋Š” ๋ถ„์€ ์œ„ ๋‚ด์šฉ์ด ์—†์„ ๊ฑฐ์—์š”.

https://start.spring.io/

์œ„ ์‚ฌ์ดํŠธ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , ๋‚ด๋ ค ๋ฐ›์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.


์ดˆ๊ธฐ ์ข…์†์„ฑ์€ ์œ„์˜ ๊ฒƒ๋“ค์„ ์‚ฌ์šฉํ•ด์„œ ์‹ค์Šตํ•ด ๋ณด๋ ค๊ณ  ํ•ด์š”.

์ƒ์„ฑ์„ ๋ˆŒ๋Ÿฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์ค„๊ฒŒ์š”.


build.bradle

๋ฐ˜์‘ํ˜•
dependencies {
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-graphql'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    runtimeOnly 'com.h2database:h2'
    runtimeOnly 'com.mysql:mysql-connector-j'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework:spring-webflux'
    testImplementation 'org.springframework.graphql:spring-graphql-test'
}






์œ„์™€ ๊ฐ™์ด ์—ด์‹ฌํžˆ Setting ์ค‘์ธ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

Spring for GraphQL์€ JPA ํ™˜๊ฒฝ์—์„œ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ด์ฃผ๊ณ  ์žˆ๋‹ค๊ณ  ํ•ด์š”.
๊ทธ๋ฆฌ๊ณ , WebFlux ํ™˜๊ฒฝ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ฃผ๋‹ˆ๋Š” Web MVC ๊ธฐ๋ฐ˜์œผ๋กœ ์‹ค์Šตํ•ด ๋ณผ๊ฑฐ์—์š”.

์ตœ์ดˆ ํ”„๋กœ์ ํŠธ Root(์ตœ์ƒ์œ„) Directory(๋””๋ ‰ํ„ฐ๋ฆฌ) ์•ˆ์— ์•„๋ž˜์™€ ๊ฐ™์ด ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์ฃผ์–ด์•ผ ํ•ด์š”.

 

์šฐ์ธก ์ƒ๋‹จ GraphQL ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜๋ฅผ ๋ˆŒ๋Ÿฌ ์„ค์น˜ ์ง„ํ–‰

 

.graphqlconfig

{
"name": "Graphql-Example",
"schemaPath": "src/main/resources/graphql/schema.graphqls",
"extensions": {}
}


์œ„์™€ ๊ฐ™์ด GraphQL ์„ค์ • ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.
์ด ํŒŒ์ผ์€ ์ด ์ „์— ๊ณต๋ถ€ํ–ˆ์—ˆ๋˜ GraphQL Schema(์Šคํ‚ค๋งˆ) ๋ฐ ๊ด€๋ จ ์„ค์ • ์ •๋ณด๋ฅผ ์ •์˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•˜๋Š” ํŒŒ์ผ์ด์—์š”.

์ฆ‰, GraphQL ์Šคํ‚ค๋งˆ์˜ ์œ„์น˜ ๋ฐ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์„ค์ •์„ ํ•˜๋Š”๋ฐ ์ด์šฉ๋˜๋Š” ๊ฒƒ์ด์—์š”.

๊ทธ๋Ÿผ ์†์„ฑ๋“ค์„ ์•Œ์•„๋ณผ๊ฒŒ์š”.

โˆ™ name: GraphQL ์„ค์ • ์ด๋ฆ„์œผ๋กœ ์œ„์—์„œ๋Š” "Graphql-Example"๋กœ ์ง€์ •. ์ด๋ฆ„์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํ”„๋กœ์ ํŠธ ๋˜๋Š” Application(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜)์˜ ์ด๋ฆ„๊ณผ ๊ด€๋ จ.

โˆ™ schemaPath: GraphQL ์Šคํ‚ค๋งˆ ํŒŒ์ผ ๊ฒฝ๋กœ ์ง€์ •. ์ด ๊ฒฝ๋กœ๋Š” ํ”„๋กœ์ ํŠธ ์•ˆ์—์„œ GraphQL ์Šคํ‚ค๋งˆ ํŒŒ์ผ ์œ„์น˜ ์ง€์ •.

โˆ™ extensions: ์ถ”๊ฐ€์  ์„ค์ • ์ง€์ •์„ ์œ„ํ•œ ์†์„ฑ์ด๋ฉฐ, ํ•„์š”์— ๋”ฐ๋ผ ์ถ”๊ฐ€์ ์ธ GraphQL ์„ค์ •์„ ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ.

 

์ด๋ฒˆ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•ด ๋ณผ๊ฑด๋ฐ, ์ฃผ๋‹ˆ๋Š” ์ž„๋ฒ ์ด๋“œ H2 DB์˜ In-Memory Mode๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๋ ค๊ณ  ํ•ด์š”. ์ข…์†์„ฑ์€ ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ ์‹œ Spring Initalizr์—์„œ ์ถ”๊ฐ€ํ–ˆ์–ด์š”.

application.yml


์œ„์™€ ๊ฐ™์ด application.yml์— ๋“ฑ๋กํ•ด ์ฃผ๋ฉด H2 DB๋ฅผ ๊ตณ์ด ์„ค์น˜ํ•˜์ง€ ์•Š์•„๋„ ํ…Œ์ŠคํŠธ ์šฉ์œผ๋กœ ์•Œ๋งž๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.


spring:
  datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:{DB ์ด๋ฆ„}
    username: sa
    password:


๋งŒ์•ฝ application.yml ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์œ„์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋˜๊ณ ,

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:{DB ์ด๋ฆ„}
spring.datasource.username=sa
spring.datasource.password=


properties๋Š” ์œ„์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด ์ฃผ๋ฉด ๋ผ์š”.


์ผ๋‹จ ์—ฌ๊ธฐ๊นŒ์ง€ ์„ค์ •ํ•˜๊ณ , ์„œ๋ฒ„๋ฅผ ๊ธฐ๋™ ์‹œ์ผœ ๋ณด๋ฉด


์œ„์™€ ๊ฐ™์ด ์ •์ƒ์ ์œผ๋กœ ๊ธฐ๋™ ๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.


http://localhost:8080/h2-console


๊ทธ๋Ÿผ ์œ„์™€ ๊ฐ™์ด H2-console์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์–ด์š”.




์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•˜๊ณ , ์—ฐ๊ฒฐ์„ ํ•˜๋ฉด Embedded H2 DB๋ฅผ In-memory Mode๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.


/src/main/resources/init/database


Mock Data(๋ฐ์ดํ„ฐ)๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์œ„์™€ ๊ฐ™์ด Directory(๋””๋ ‰ํ„ฐ๋ฆฌ)๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.

/src/main/resources/init/database


๊ทธ๋ฆฌ๊ณ  ์œ„์™€ ๊ฐ™์ด data.sql๊ณผ schema.sql์„ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.


schema.sql์€ ๋ง ๊ทธ๋Œ€๋กœ ๋ฏธ๋ฆฌ DB์™€ Table ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ณณ์ด๊ณ ,
data.sql์€ Table์— ๋ฏธ๋ฆฌ ๋„ฃ์–ด๋‘˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ณณ์ด์—์š”.

์–„์ฝ”๋‹˜์˜ ๊ฐ•์˜์—์„œ ์‚ฌ์šฉ๋œ csv File(ํŒŒ์ผ) ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์กฐ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด๋‘˜๊ฒŒ์š”.


equipments.csv

 

schema.sql

 

data.sql




teams.csv



schema.sql



data.sql








peoples.csv

 

schema.sql

 

data.sql







roles.csv

 

schema.sql

 

data.sql







softwares.csv

 

schema.sql

 

data.sql







supplies.csv

 

schema.sql

 

data.sql


์œ„์™€ ๊ฐ™์ด schema.sql๊ณผ data.sql์„ ๋งŒ๋“  ๋’ค ์„œ๋ฒ„๋ฅผ ๊ตฌ๋™ ์‹œํ‚ค๋ฉด

select * from equipment

 

select * from people


์œ„์™€ ๊ฐ™์ด H2 DBMS์— Mock ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜ ์ž…๋ ฅ๋œ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

 

์ด์ œ ๋‹ค์‹œ GraphQL ์‚ฌ์šฉ์„ ์œ„ํ•œ ์„ค์ •์„ ํ•ด ๋ณผ๊ฒŒ์š”.

application.yml

728x90
  graphql:
    graphiql:
      enabled: true
      printer:
        enable: true


์œ„์™€ ๊ฐ™์ด ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ์–ด์š”.

์œ„ ๋‚ด์šฉ์„ ๋ถ„์„ํ•ด ๋ณด๋ฉด graphipql enable์„ ํ—ˆ์šฉํ•˜๋ฉด localhost:8080/h2-console๊ณผ ๊ฐ™์ด localhost:8080/graphiql์„ ํ†ตํ•ด Query Test๊ฐ€ ๊ฐ€๋Šฅํ•œ ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ด ์ „์— ๊ณต๋ถ€ํ–ˆ๋˜ Apollo์˜ Playground๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ •์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์ข‹์„ ๊ฑฐ ๊ฐ™์•„์š”.

๋˜ํ•œ, ์ด ๋ฐฉ๋ฒ• ๋ง๊ณ , ์ธํ…”๋ฆฌ์ œ์ด์˜ GraphQL Plugin(ํ”Œ๋Ÿฌ๊ทธ์ธ)์„ ์„ค์น˜ํ•ด์„œ ์ธํ…”๋ฆฌ์ œ์ด์—์„œ๋„ ์ง์ ‘ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ , Postman์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์–ด์š”.

printer enable์„ ํ—ˆ์šฉํ•ด์ค€ ๊ฒƒ์€ jpa์˜ show-sql์ด ์ถœ๋ ฅ๋  ๋•Œ, GraphQL Query ๋‚ด์šฉ๋„ ์ถœ๋ ฅ๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•จ์ด์—์š”.

 

 

 

 

 

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

    ๐Ÿ”ฝ  Equipment

        ๐Ÿ“ฆ Entity

์‹ค์Šต์„ ์œ„ํ•œ Entity๋ฅผ ๋งŒ๋“ค์–ด ๋ณผ๊ฒŒ์š”.

์–„์ฝ”๋‹˜์˜ ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉด์„œ ๊ณต๋ถ€ํ–ˆ์„ ๋•Œ, Equipment, people, team, supply๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ,
์ฃผ๋‹ˆ๋„ ์ด๊ฒƒ์— ์ดˆ์ ์„ ๋งž์ถฐ ์‹ค์Šต์„ ํ•ด๋ณด๋ ค ํ•ด์š”.

๊ธ€์—์„œ๋Š” Equipment๋งŒ ์ž‘์„ฑํ•˜๊ณ , ๋‚˜๋จธ์ง€๋Š” Git Hub์—์„œ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋ด์ฃผ์‹œ๋ฉด ์ข‹์„ ๊ฑฐ ๊ฐ™์•„์š”.

https://github.com/junyharang-coding-study/GraphQL-Study/tree/master/graphql-test

Equipment.java

 

Equipment.java


Equipment Entity๋ฅผ ์œ„์™€ ๊ฐ™์ด ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.




        ๐Ÿ“ฆ EquipmentResolver

์ด๋ฒˆ์—๋Š” Resolver(๋ฆฌ์กธ๋ฒ„) Code๋ฅผ ๋งŒ๋“ค์–ด ๋ณผ๊ฒŒ์š”.
Resolver(๋ฆฌ์กธ๋ฒ„)๋Š” REST API๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค๋ฉด Controller๋ผ๊ณ  ๋ช…๋ช…ํ–ˆ์„๊ฑฐ์—์š”.

EquipmentResolver.java

 

EquipmentResolver.java

 
27 ~ 31๋ฒˆ์งธ ์ค„์€ Create ์ฆ‰, ๋‚ด์šฉ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ Router(๋ผ์šฐํ„ฐ)์—์š”.

์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ๊ฒƒ์€ @Argument("input")์ด์—์š”.
์ด ๋‚ด์šฉ์€ GraphQL Query์˜ input ์ด๋ผ๋Š” ์ด๋ฆ„์˜ ์ธ์ž์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์œผ๋กœ
EquipmentRequestDto๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ›๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.



์œ„ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์œ„์™€ ๊ฐ™์ด ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ ค์ฃผ๊ฒŒ ๋˜๋Š”๋ฐ, ์ด ๋•Œ, GraphQL Schema(์Šคํ‚ค๋งˆ)์—์„œ ํ•ด๋‹น ๋ฎคํ…Œ์ด์…˜์ด๋‚˜, ์ฟผ๋ฆฌ์— ์ „๋‹ฌ๋˜๋Š” ์ธ์ž์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ผ์š”. ์—ฌ๊ธฐ์„œ Input์€ GraphQL ์ฟผ๋ฆฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ณ€์ˆ˜ ์ด๋ฆ„์ด์—์š”.

GraphQL์—์„œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฎคํ…Œ์ด์…˜์˜ ์ž…๋ ฅ๊ฐ’์„ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด ๋•Œ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ํŠน์ •ํ•œ ์ด๋ฆ„์œผ๋กœ ๋ช…๋ช…ํ•˜๊ฒŒ ๋ผ์š”. ์ด๋ ‡๊ฒŒ ๋ช…๋ช…๋œ ๊ฐ์ฒด๋Š” GraphQL ์ฟผ๋ฆฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” Variable(๋ณ€์ˆ˜) ์—ญํ• ์„ ํ•˜๊ฒŒ ๋ผ์ฃ .

์ฟผ๋ฆฌ๋ฅผ ๋˜์งˆ ๋Œ€ ์‚ฌ์šฉ๋˜๋Š” ์ฟผ๋ฆฌ๋ฌธ์„ ๋ถ„์„ํ•ด ์ฃผ๋ฉด saveForEquipment ๋ฎคํ…Œ์ด์…˜์€ EquipmentRequestDto ๊ฐ์ฒด๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ฒŒ ๋˜๊ณ , ์ด ๊ฐ์ฒด๋Š” input์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์ •์˜๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ๋ณ€์ˆ˜๋ช…์„ ์ง€์ •ํ•  ๋•Œ, Java Code์—์„œ ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด @Argument๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฆ„์„ ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผ ํ•ด์š”.

์ •๋ฆฌํ•˜๋ฉด Java Code์—์„œ @Argument("input)์€ GraphQL์—์„œ ์ „๋‹ฌ๋˜๋Š” input ๋ณ€์ˆ˜๋ฅผ EquipmentRequestDto ๊ฐ์ฒด๋กœ ๋ฐ›๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ Annotation(์–ด๋…ธํ…Œ์ด์…˜)์ด์—์š”. ์ด๋ฅผ ํ†ตํ•ด GraphQL ์ฟผ๋ฆฌ์—์„œ ์ •์˜ํ•œ ๋ณ€์ˆ˜์™€ Java Code์—์„œ์˜ Method(๋ฉ”์„œ๋“œ) ์ธ์ž๋ฅผ Mapping(๋งคํ•‘)ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.


36 ~ 44๋ฒˆ์งธ ์ค„ getEqupmentList()๋Š” ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๊ฒ€์ƒ‰๊ณผ Paging ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•œ ๋ผ์šฐํ„ฐ์—์š”.

@Argument๋Š” REST API๋กœ ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„ ์‹œ ์‚ฌ์šฉํ•˜๋Š” @RequestBody, @RequestParam๊ณผ ๊ฐ™์ด ์ธ์ˆ˜ ๊ฐ’์„ ์ง€์ •ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Annotaion(์–ด๋…ธํ…Œ์ด์…˜)์ด์—์š”.

์ฆ‰, GraphQL Query ์ธ์ˆ˜ ์ •์˜ ๋•Œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ๊ฐ๊ฐ์˜ Method(๋ฉ”์„œ๋“œ) Parameter(ํŒŒ๋ผ๋ฏธํ„ฐ)๋Š” GraphQL Query์—์„œ ์ „๋‹ฌ๋œ ๋งค๊ฐœ ๋ณ€์ˆ˜์— Mapping(๋งคํ•‘) ๋˜๊ฒŒ ๋œ๋‹ต๋‹ˆ๋‹ค.


 

EquipmentResolver.java


46 ~ 49๋ฒˆ์งธ ์ค„์€ ์ƒ์„ธ ์กฐํšŒ๋ฅผ ์œ„ํ•œ ๋ฉ”์„œ๋“œ์—์š”.
ID ๊ฐ’์„ ์ธ์ž๋กœ ๋ฐ›์•„ ํ•ด๋‹น ๊ฐ’์— ์ƒ์„ธํ•œ ๋‚ด์šฉ์„ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ์—์š”.

51 ~ 54๋ฒˆ์งธ ์ค„์€ ์ˆ˜์ • ์ž‘์—…์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ์—์š”.
์ˆ˜์ •์„ ์œ„ํ•œ DTO ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌ ๋  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.






 

 

        ๐Ÿ“ฆ EquipmentService & EquipmentServiceImpl

EquipmentService.java
EquipmentService.java



EquipmentServiceImpl.java



EquipmentServiceImpl.java


saveForEquipment()๋ฅผ ๋ถ„์„ํ•ด ๋ณด๋ฉด ์ตœ์ดˆ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ DTO ๊ฐ์ฒด๊ฐ€ Null์ธ์ง€ ํ™•์ธํ•˜๊ณ ,
Null์ด๋ฉด 204 Error๋ฅผ ๋‚ด๋ณด๋‚ด๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

๋งŒ์•ฝ Null์ด ์•„๋‹ˆ๋ผ๋ฉด JPA์˜ save()๋ฅผ ์ด์šฉํ•˜์—ฌ DTO ๊ฐ์ฒด๋ฅผ Entity ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ ์‹œ์ผœ ์ „๋‹ฌํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ณ , ์ €์žฅ๋œ ID๋ฅผ ๋ฐ˜ํ™˜๋˜๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

์ฐธ๊ณ ๋กœ DefaultResponse๋Š” ๋ฐ˜ํ™˜๊ฐ’์„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ๋ฌถ์–ด ์ „๋‹ฌํ•˜๋Š”๋ฐ, Http Status Code์™€ Message ๊ทธ๋ฆฌ๊ณ , ๋ฐ˜ํ™˜ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด์ด๊ณ , Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๊ฐ’๋„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์—์š”.


EquipmentServiceImpl.java


getEquipmentList()
๋Š” ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ๊ณผ Paging ์ฒ˜๋ฆฌ๋ฅผ ํ•จ๊ป˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“  ๋ฉ”์„œ๋“œ์—์š”.


page๋Š” ์กฐํšŒ ๋Œ€์ƒ Page ๋ฒˆํ˜ธ์ด๊ณ , size๋Š” ํ•œ Page์— ๋‹ด์„ ์š”์†Œ ๊ฐœ์ˆ˜์—์š”.
๊ทธ๋ฆฌ๊ณ , ๋‚˜๋จธ์ง€ ์ธ์ž๊ฐ’๋“ค์€ ๊ฒ€์ƒ‰์„ ์œ„ํ•ด ์‚ฌ์šฉํ•  ๊ฐ’๋“ค์ด์—์š”.

52 ~ 57๋ฒˆ์งธ ์ค„๊นŒ์ง€ ๋ถ„์„ํ•ด ๋ณด๋ฉด QueryDsl์„ ํ†ตํ•ด ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ์ฆ‰, ๋™์  ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•ด ์ฃผ๋Š”๋ฐ, ์ด ๋•Œ, ๊ฒ€์ƒ‰์„ ์œ„ํ•ด ๋‹ด๊ธด ๊ฐ๊ฐ์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ EquipmentSearchRequestDto ๊ฐ์ฒด์— ๋„ฃ์–ด ์ „๋‹ฌํ•ด ์ฃผ๊ณ , Paging ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ฐ์ฒด๋ฅผ ์ฒ˜๋ฆฌํ•œ ๋’ค ๊ทธ ๊ฐ์ฒด๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌํ•ด ์ฃผ๊ณ  ์žˆ์–ด์š”.

๊ทธ๋ ‡๊ฒŒ ํ•œ ๋’ค 59๋ฒˆ์งธ ์ค„์— QueryDsl์„ ์ด์šฉํ•˜์—ฌ ์กฐํšŒ๋œ ๊ฐ์ฒด์— ๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์—†๋‹ค๋ฉด ๊ฐ’์„ ๋ชป ์ฐพ์•˜๋‹ค๋Š” ๋‚ด์šฉ์„ ์ „๋‹ฌํ•˜๊ณ , ์žˆ๋‹ค๋ฉด Page ๊ฐ์ฒด๋กœ ๋ฌถ์ธ ๊ฐ์ฒด๋ฅผ List๋กœ ๋ณ€ํ™˜ ํ•˜๊ณ , ๊ทธ List ๊ฐ์ฒด๊ฐ€ ๋น„์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ๋ฐ˜ํ™˜ ํ•ด์ฃผ๊ณ , ๋˜ ๋น„์–ด ์žˆ๋‹ค๋ฉด ๊ฐ’์„ ๋ชป ์ฐพ์•˜๋‹ค๋Š” ๋‚ด์šฉ์„ ์ „๋‹ฌํ•ด ์ฃผ๋Š” ๊ฒƒ์ด์—์š”.

Page ๊ฐ์ฒด๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•ด ๋ฒ„๋ฆฌ๋ฉด 

query.graphqls

 

schema.graphqls


์œ„์™€ ๊ฐ™์ด Root Query type๊ณผ ๋ฐ˜ํ™˜ ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•ด ์ฃผ์—ˆ๋Š”๋ฐ, DefaultListResponse์— String, Int, Boolean ์™ธ์— ๋‚ด์šฉ์„ ๋„ฃ์œผ๋ฉด ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ ๋ฒ„๋ ค์„œ List๋กœ ๋ณ€ํ™˜ํ•ด์„œ DefaultListRespone Type 4๋ฒˆ์งธ ์ค„์ฒ˜๋Ÿผ ๋ฐ˜ํ™˜๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ List๋กœ ๋ณ€ํ™˜ํ•ด ์ค€ ๊ฒƒ์ด์—์š”.



EquipmentResolverImpl.java


getEquipment()๋Š” ID๋ฅผ ์ž…๋ ฅ ๋ฐ›์•„ ํ•ด๋‹น ๋‚ด์šฉ์„ ์ƒ์„ธ ์กฐํšŒํ•˜๋Š” ๋ฉ”์„œ๋“œ์—์š”.
JPQL์„ ์ด์šฉํ•˜์—ฌ ID๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒํ•˜๊ณ , ํ•ด๋‹นํ•˜๋Š” Entity๊ฐ์ฒด๋ฅผ ๋ฐ›์€ ๋’ค Null Safety์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด Optional<>๋กœ ๊ฐ์‹ธ์ฃผ๊ณ , ํ•ด๋‹น ๊ฐ’์ด Null์ด ์•„๋‹ˆ๋ผ๋ฉด ResponseDTO๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ด์ฃผ๊ณ , Null์ด๋ผ๋ฉด ๊ฐ’์„ ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค๊ณ  ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.


EquipmentResolverImpl.java


updateEquipment()๋Š” ์ˆ˜์ •์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋กœ ์ˆ˜์ • ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ฐ’์„ ๋‹ด์€ DTO ๊ฐ์ฒด์— ๋‹ด๊ธด ID๊ฐ’์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒํ•˜์—ฌ ํ•ด๋‹น ๋‚ด์šฉ์ด ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ , getEquipment()๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋ผ์š”.

EquipmentResolverImpl.java


์ด ๋ฉ”์„œ๋“œ๋Š” ์ตœ์ดˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒ๋œ ๊ฐ์ฒด๊ฐ€ Null์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ , Null์ด๋ผ๋ฉด Null์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , Null์ด ์•„๋‹ˆ๋ผ๋ฉด ์ˆ˜์ •์„ ์œ„ํ•ด Client(ํด๋ผ์ด์–ธํŠธ)์—์„œ ์ „๋‹ฌํ•œ ๊ฐ’๋“ค์ด ๋“ค์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ๋“ค์–ด ์žˆ๋Š” ๊ฒƒ์€ update()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Entity์— ๊ฐ’์„ Update ํ•œ ๋’ค Entity๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.


EquipmentResolverImpl.java


๊ทธ๋Ÿฐ ๋’ค ์œ„์—์„œ Null์„ ์ „๋‹ฌํ•˜๋Š” ๋กœ์ง์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ Null Check๋ฅผ ํ•ด ์ฃผ๊ณ , Null์ด๋ฉด ์ˆ˜์ • ๋Œ€์ƒ์„ ๋ชป ์ฐพ์•˜๋‹ค๊ณ  ๋ฐ˜ํ™˜ํ•ด์ฃผ๊ณ , Null์ด ์•„๋‹ˆ๋ฉด JPA์˜ save()๋ฅผ ํ†ตํ•ด Update ์ฟผ๋ฆฌ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๊ฒŒ ํ•œ ๋’ค ํ•ด๋‹น ๊ฐ’์˜ ID๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.


EquipmentResolverImpl.java


๋งˆ์ง€๋ง‰์œผ๋กœ ์‚ญ์ œ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” deleteEquipment()์—์š”.

์—ญ์‹œ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ „๋‹ฌ๋œ ID๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒํ•˜๊ณ , ๊ทธ ๊ฐ’์ด ์กด์žฌํ•œ๋‹ค๋ฉด JPA deleteByID()๋ฅผ ์ด์šฉํ•˜์—ฌ ์‚ญ์ œ๋ฅผ ํ•ด ์ค€ ๋’ค ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” ๋ฐ˜ํ™˜ ๊ฐ’์ด Void์ด๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ „๋‹ฌํ•œ ID๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์กฐํšŒ ์‹œ ํ•ด๋‹น ๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค๊ณ  ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

 

 

 

        ๐Ÿ“ฆ EquipmentRepository

EquipmentRepository.java


findAllByStringId()๋Š” ์ƒ์„ธ ์กฐํšŒ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ์ธ๋ฐ, ์• ์ดˆ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ID๊ฐ€ Long๊ณผ ๊ฐ™์€ ์ •์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฌธ์ž์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— JPQL์„ ํ†ตํ•ด ์ฒ˜๋ฆฌ ๋  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ์ค€ ๊ฒƒ์ด์—์š”.


์ด์ œ QueryDsl์„ ์ด์šฉํ•œ ๋™์  ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ํ–ˆ๋Š”์ง€ ์•Œ์•„๋ณผ๊ฒŒ์š”.

EquipmentQueryDslRepository.java

 

EquipmentQueryDslRepository.java


์ตœ์ดˆ findBySearchAndPaging()์€ ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๊ฒ€์ƒ‰๊ณผ Paging ์ฒ˜๋ฆฌ๋ฅผ ๋ชจ๋‘ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ง„ ๋ฉ”์„œ๋“œ์—์š”.

26๋ฒˆ์งธ ์ค„์€ JPAQueryFactory๋ฅผ ์ฃผ์ž… ๋ฐ›์•„ Member Variable(๋ฉค๋ฒ„ ๋ณ€์ˆ˜)๋กœ ์ €์žฅํ•˜๋Š”๋ฐ, ์ด๊ฒƒ์€ QueryDsl์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์  ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ์ด์—์š”.

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ๊ฐ–์€ DTO์™€ Paging ์ •๋ณด๋ฅผ ๋‹ด์€ Pageable์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๊ฑธ ์•Œ ์ˆ˜ ์žˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค JPAQueryFactory๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ QueryDsl ์ฟผ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๋Š”๋ฐ, Projections.constructor()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์กฐํšŒ๋œ ๊ฒฐ๊ณผ๋ฅผ EquipmentResponseDto๋กœ ๋งคํ•‘๋˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋ฆฌ๊ณ , from(equipment)๋ฅผ ์ด์šฉํ•˜์—ฌ equipment Entiry๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ฟผ๋ฆฌ๊ฐ€ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

where ์กฐ๊ฑด์„ ์ด์šฉํ•˜์—ฌ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ์ง€์ •ํ•ด ์ฃผ์—ˆ๋Š”๋ฐ, eqEquipmentId(), eqUsedBy(), eqNewOrUsed()๋ฅผ ๊ฐ๊ฐ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด๋‹น ์กฐ๊ฑด์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.


EquipmentQueryDslRepository.java


์œ„ ๋ฉ”์„œ๋“œ๋“ค์€ Field(ํ•„๋“œ)์— ๋Œ€ํ•œ ๋™์ ์ธ ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ์—์š”.
์ „๋‹ฌ ๋œ ์ธ์ˆ˜ ๊ฐ’์ด ๋น„์–ด ์žˆ๋‹ค๋ฉด Null์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด equipment.<ํ•ด๋‹น ๋ณ€์ˆ˜>.eq(ํ•ด๋‹น ๋ณ€์ˆ˜)๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ–ˆ์–ด์š”.
์ด ๋•Œ BooleanExpression Type์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์ด๋Š” QueryDsl์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์กฐ๊ฑด์„ ๋‚˜ํƒ€๋‚ด๊ฒŒ ํ•ด์š”.

์ด๋ ‡๊ฒŒ ํ•ด์„œ ๋™์  ์กฐ๊ฑด ์ƒ์„ฑ ๋ฉ”์„œ๋“œ๋“ค์„ ๊ฐ๊ฐ ๋งŒ๋“ค์–ด์ฃผ๊ณ , ๊ฒ€์ƒ‰ ์กฐ๊ฑด์ด ์ฃผ์–ด์ง„ ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น ํ•„๋“œ์— ๋Œ€ํ•œ ์กฐ๊ฑด์„ ์ƒ์„ฑํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ Null์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ ํ•ด๋‹น ์กฐ๊ฑด์ด ๊ฒ€์ƒ‰๋˜์ง€ ์•Š๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ค€ ๊ฒƒ์ด์—์š”.

EquipmentQueryDslRepository.java


๋‹ค์‹œ ์ด ๋ถ€๋ถ„์„ ๊ณ„์† ๋ถ„์„ํ•ด ๋ณผ๊ฒŒ์š”.


41๋ฒˆ์งธ ์ค„์— orderBy()๋ฅผ ํ†ตํ•ด ID๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค 44๋ฒˆ์งธ ์ค„์— PagingProcessUtil.queryDslPagingProcessing()์„ ํ†ตํ•ด QueryDsl์„ ์‚ฌ์šฉํ•œ Paging ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋ชจ๋“  ๋‚ด์šฉ๋“ค์€ PageImpl๋กœ ๊ฐ์‹ธ Spring Data JPA์˜ Page ๊ฐ์ฒด์— ๋‹ด์•„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด ์ค€ ๊ฒƒ์ด์—์š”.


PagingProcessUtil.queryDslPagingProcessing


์œ„ ์ฝ”๋“œ๋Š” QueryDsl์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑํ•œ ์ฟผ๋ฆฌ์— ๋Œ€ํ•ด Paging ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ Utility ๋ฉ”์„œ๋“œ์—์š”.

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” ์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œ (<T>)์ธ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋–ค ํƒ€์ž…์˜ QueryDsl ๊ฒฐ๊ณผ๋ฅผ ๋‹ค๋ฃจ๋”๋ผ๋„ ์œ ์—ฐํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ์ค€ ๊ฒƒ์ด์—์š”.

์ฆ‰, ์—ฌ๋Ÿฌ ๋ชฉ๋ก ์กฐํšŒ ๋กœ์ง์ด ๋งŒ๋“ค์–ด ์งˆํ…๋ฐ, ๊ณตํ†ต ๋ถ€๋ถ„์œผ๋กœ Paging ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ ๊ฑฐ์—์š”.

JPAQuery<T> query ์ธ์ž๊ฐ’์€ QueryDsl์„ ์ด์šฉํ•˜์—ฌ ๋งŒ๋“ค์–ด์ง„ SQL Query๋ฌธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ผ์š”.
Pageable ์ธ์ž๊ฐ’์„ Srping Data JPA์—์„œ ์ œ๊ณตํ•˜๋Š” Paging ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์—์š”.

31๋ฒˆ์งธ ์ค„์— ๊ฒฐ๊ณผ๋ฅผ ๋‹ด์„ List๋ฅผ ์ดˆ๊ธฐํ™” ํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค 33๋ฒˆ์งธ ์ค„์— ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ (๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒ๋œ ๊ฒฐ๊ณผ๋ฌผ) ๊ฐœ์ˆ˜๊ฐ€ 2๊ฐœ ์ด์ƒ์ธ ๊ฒฝ์šฐ์—๋งŒ Paging ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด ๋ถ„๊ธฐ๋ฌธ์„ ์ž‘์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.

์ด๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ํ•˜๋‚˜์ผ ๋•Œ ์•„๋ฌด ๊ฐ’๋„ ๋ฐ˜ํ™˜ ๋ฐ›์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

34 ~ 36๋ฒˆ์งธ ์ค„์€ Paging ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ฒฐ๊ณผ๋ฅผ List๋กœ ๋‹ด๋„๋ก ํ•ด ์ฃผ๋Š” ๋ถ€๋ถ„์ด์—์š”.

ํ•˜์ง€๋งŒ, 2๋ณด๋‹ค ์ž‘๋‹ค๋ฉด ์ฆ‰, ๊ฒฐ๊ณผ๊ฐ€ 1๊ฐœ๋ผ๋ฉด Paging ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๊ณ , ๊ทธ๋Œ€๋กœ ๊ฒฐ๊ณผ๊ฐ’์„ List์— ๋„ฃ์–ด์ค€ ๊ฒƒ์ด์—์š”.
์™œ๋ƒํ•˜๋ฉด ๋ฐ˜ํ™˜๊ฐ’์€ List์ด๊ธฐ ๋•Œ๋ฌธ์— List๋กœ ๋‹ด์•„์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ํ•ด๋‹น List๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ฃผ๋Š” ๋กœ์ง์ด์—์š”.

์ด๋ ‡๊ฒŒ Paging ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์˜ ๊ฐœ์ˆ˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒฐ์ •ํ•˜๊ณ , ๊ฒฐ๊ณผ๊ฐ€ 1๊ฐœ์ธ ๊ฒฝ์šฐ์—๋Š” Paging ์ฒ˜๋ฆฌ๋ฅผ ์ƒ๋žตํ•˜์—ฌ ์ตœ์ ํ™”๋œ ๋™์ž‘์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฃผ๋‹ˆ๊ฐ€ ๊ณ ์•ˆํ•œ ๋ฉ”์„œ๋“œ์—์š”.

 

 

 

 

    ๐Ÿ”ฝ graphqls(Schema)

        ๐Ÿ“ฆ schema.graphqls

resources/graphql/schema.graphqls

 

 

 

 

 

        ๐Ÿ“ฆ query.graphqls

resources/graphql/query.graphqls



 

 

 

        ๐Ÿ“ฆ mutation.graphqls

resources/graphql/mutation.graphqls



 

 

 

        ๐Ÿ“ฆ equipment.graphqls

resources/graphql/equipment/equipment.graphqls



์œ„์™€ ๊ฐ™์ด GraphQL ์Šคํ‚ค๋งˆ๋ฅผ ๊ตฌ์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.

 

 

 

    ๐Ÿ”ฝ ์ž˜ ๋งŒ๋“ค์—ˆ๋‚˜? ๐Ÿค”

        ๐Ÿ“ฆ Eequipment CRUD Test

๋งŒ๋“ค์–ด์ง„ ๋กœ์ง์„ ์ด์šฉํ•˜์—ฌ CRUD Test๋ฅผ ์ง„ํ–‰ํ•ด ๋ณผ๊ฒŒ์š”.

http://localhost:8080/graphiql


์œ„์™€ ๊ฐ™์ด Apollo Playgroud์™€ ๊ฐ™์€ ์„œ๋น„์Šค๋ฅผ Spring For GraphQL๋„ ์ œ๊ณตํ•˜๋Š”๋ฐ ์ด๋ฆ„์ด Graphiql ๊ฐ™์•„์š”.
์ฐธ๊ณ ๋กœ ์ด ์นœ๊ตฌ๋Š” ๋กœ์ง์ด ๊ตฌํ˜„๋˜์–ด์•ผ ์˜ฌ๋ผ์™€์š”.

๋กœ์ง์ด ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ application.yml์— ์„ค์ •๋งŒ ํ•ด ์ฃผ์—ˆ๋‹ค๊ณ  ํ•ด์„œ URL์„ ์ž…๋ ฅํ•˜๋ฉด White Error๋งŒ ๋‚˜์˜ฌ๊ฑฐ์—์š”.
์ฃผ๋‹ˆ๋Š” ๊ทธ๋ž˜์„œ ๊ต‰์žฅํžˆ ๋‹นํ™ฉํ–ˆ๊ฑฐ๋“ ์š”.


graphiql -&nbsp;findBygetEquipmentListSeachEquipmentIdAndPaging

query findBygetEquipmentListSeachEquipmentIdAndPaging {
  getEquipmentList(
    equipmentId: "machanical keyboard",
    page: 1,
    size: 3
  ) {
    statusCode,
    message,
    data,
    pagination
  }
}


ID๊ฐ’์€ ๊ณ ์œ ํ•œ๋ฐ, ID๋ฅผ ๊ฒ€์ƒ‰ํ–ˆ๊ณ , Paging ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ํ˜„์žฌ Page ์œ„์น˜ ๊ฐ’(page)์™€
ํ•ด๋‹น Page์— ์ถœ๋ ฅ๋  ์š”์†Œ ๊ฐœ์ˆ˜(size)๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.


์œ„์—์„œ QueryDsl์„ ์ด์šฉํ•ด์„œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ํ•˜๋‚˜์ผ ๊ฒฝ์šฐ Paging ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๊ณ , SQL Query๋ฅผ ๋‚ ๋ฆฌ๊ฒŒ ๋งŒ๋“  ๋กœ์ง์ด ์žˆ์—ˆ๋Š”๋ฐ, ํ•ด๋‹น ๋กœ์ง์ด ์—†์—ˆ๋‹ค๋ฉด ์œ„์— data๋Š” data:[] ์ด๋Ÿฐ์‹์œผ๋กœ ๋ฐ˜ํ™˜ ๋˜์—ˆ์„ ๊ฒƒ์ด์—์š”.

์™œ๋ƒํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ SQL๋ฌธ์œผ๋กœ offset๊ณผ limit ์ ˆ ์ฒ˜๋ฆฌ๊ฐ€ ์ด๋ค„์กŒ๋Š”๋ฐ, ๊ฐ’์€ ํ•˜๋‚˜๋ฐ–์— ์—†๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

๋ฌผ๋ก  Limit ์ ˆ์— ๊ฐ’์„ 1๋กœ ์ฃผ๊ฑฐ๋‚˜ ํ•˜๋ฉด ๋˜๊ฒ ์ง€๋งŒ, ์‹ค์ œ ์„œ๋น„์Šค์—์„œ ํด๋ผ์ด์–ธํŠธ ์ธก์€ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๊ฐ€ ๋ช‡ ๊ฐœ๊ฐ€ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๋Š”๋ฐ, ์ด๊ฑธ 1๊ฐœ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค๊ฐ€ ๋ง์ด ๋ ๊นŒ?๊ฐ€ ์ฃผ๋‹ˆ์˜ ๊ณ ๋ฏผ์ด์˜€๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•ด ์ค€ ๊ฒƒ์ด์—์š”.



graphiql -&nbsp;findeBygetEquipmentListPaging

 

graphiql -&nbsp;findeBygetEquipmentListPaging



query findeBygetEquipmentListPaging {
  getEquipmentList(
    page: 1,
    size: 3
  ) {
    statusCode,
    message,
    data,
    pagination
  }
}


์œ„์˜ ์ฟผ๋ฆฌ๋Š” ๊ฒ€์ƒ‰์€ ํ•˜์ง€ ์•Š๊ณ , Paging ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ฐ’๋งŒ ๋˜์กŒ์„ ๋•Œ์—์š”.



graphiql findBygetEquipmentListSeachUsedByAndPaging


์œ„์— ๋‚ด์šฉ์€ usedBy ํ•„๋“œ ๊ฒ€์ƒ‰ํ•  ๋•Œ๋ฅผ ํ…Œ์ŠคํŠธ ํ•ด ๋ณด์•˜์–ด์š”.



graphiql findBygetEquipmentListSeachNewOrUsedAndPaging

query findBygetEquipmentListSeachNewOrUsedAndPaging {
  getEquipmentList(
    newOrUsed: "used"
    page: 1,
    size: 3
  ) {
    statusCode,
    message,
    data,
    pagination
  }
}




graphiql findBygetEquipmentListSeachAllFieldAndPaging

query findBygetEquipmentListSeachAllFieldAndPaging {
  getEquipmentList(
    equipmentId: "machanical keyboard",
    usedBy: "developer",
    newOrUsed: "used"
    page: 1,
    size: 3
  ) {
    statusCode,
    message,
    data,
    pagination
  }
}




graphiql saveForEquipment

mutation saveForEquipment {
  saveForEquipment(input: {
      equipmentId: "MacBook",
      usedBy: "developer",
      count: 100,
      newOrUsed: "new"
    }) {
    statusCode,
    message,
    data
  }
}

 

์œ„์˜ ๋‚ด์šฉ์€ Equipment์˜ ๊ฐ’์„ ์ž…๋ ฅํ•˜๋Š” ์ฟผ๋ฆฌ์—์š”.



graphiql -&nbsp;updateEquipment

mutation updateEquipment {
  updateEquipment(input: {
      equipmentId: "MacBook",
      usedBy: "developer",
      count: 150
      newOrUsed: "new"
    }) {
    statusCode,
    message,
    data
  }
}


์œ„์—์„œ ์ž…๋ ฅํ–ˆ๋˜ ๊ฐ’์˜ count ํ•„๋“œ๋ฅผ 100์—์„œ 150์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ์ฟผ๋ฆฌ์—์š”.


graphiql -&nbsp;deleteEquipment

mutation deleteEquipment {
  deleteEquipment(equipmentId: "MacBook") {
    statusCode,
    message,
    data
  }
}


๊ทธ๋ฆฌ๊ณ  ๋งŒ๋“ค์—ˆ๋˜ ๊ฐ’์„ ์‚ญ์ œํ•˜๋Š” ์ฟผ๋ฆฌ์—์š”.


์ด๋ ‡๊ฒŒ ๋ชจ๋‘ ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

Equipment ์™ธ์— ๋‹ค๋ฅธ ๊ฒƒ๋“ค์€ Git Hub ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

https://github.com/junyharang-coding-study/GraphQL-Study/tree/master/graphql-test


์ด์ œ ๊ฐ•์˜์—์„œ ๋ฐฐ์› ๋˜ ์‹ค์Šต์„ ์ง„ํ–‰ํ•ด ๋ณผ๊ฒŒ์š”.

 

 

 

 

 

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

COUPANG

www.coupang.com

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

 

 

 

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

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

github.com

 

 

 

 

 

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

 

Spring for GraphQL

Spring for GraphQL์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

danawalab.github.io

 

 

 

 

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

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

qr.kakaopay.com

 

 

 

728x90
๋ฐ˜์‘ํ˜•