λ€μν κ²½νμ ν΅ν΄ μ€λ ₯μ λμ΄κ³ μΆμ μΈν΄ λμμ΄λλ€κ³Ό μ λ ΄ν κ°κ²©μΌλ‘ λμμΈμ λ°κ³ μΆμ κ³ κ°λ€μ μ°κ²°ν΄μ£Όλ μμ½ μ¬μ΄νΈ
GlowGrow - λΉλλ€(Glow)βμ βμ±μ₯νλ€(Grow)βλ₯Ό κ²°ν©ν ν©μ±μ΄
- λκ·λͺ¨ νΈλν½μ μμ μ μΌλ‘ μ²λ¦¬ν μ μλ C2C μμ½ μμ€ν μ ꡬμΆνμ¬, μΈν΄ λμμ΄λμ κ³ κ° κ°μ μνν λ§€μΉ λ° μμ½μ΄ κ°λ₯νλλ‘ ν©λλ€. MSA κΈ°λ°μΌλ‘ κ° κΈ°λ₯μ λ 립μ μΌλ‘ νμ₯ν μ μλλ‘ μ€κ³νμ¬ μλΉμ€ μ μ°μ±κ³Ό νμ₯μ±μ κ·Ήλνν©λλ€. λν μ€μκ° μλ¦Ό λ° μ±ν μ ν΅ν΄ μ¬μ©μ κ²½νμ ν₯μμν€κ³ , νλ‘λͺ¨μ , 리뷰, κ²°μ μμ€ν μ ν΅ν΄ νλ«νΌμ μ λ’°μ±κ³Ό ν¨μ¨μ±μ κ°νν©λλ€.
- Kafkaλ₯Ό νμ©ν λΉλκΈ° ν΅μ μΌλ‘ MSA ꡬ쑰 λ΄ μλΉμ€ κ° ν΅μ λΆλ΄ μ΅μν
- Zipkin, Grafanaλ₯Ό μ¬μ©ν μ ν리μΌμ΄μ λͺ¨λν°λ§μΌλ‘ μλΉμ€ μμ μ± ν보
| μ νΈμ€ | μ΄μμ | μ΄μ λΉ | λ°μ§μ° |
|---|---|---|---|
| @hosu | @twonezero | @ego2 | @ParkJinWu |
| μ μ , νλ‘ν JWT μΈμ¦/μΈκ° μλ¦Ό μλΉμ€ λ°°ν¬, CI/CD |
μμ½ μμ€ν
μλΉμ€ λ°°ν¬, CI/CD |
νλ‘λͺ¨μ
, μΏ ν° μ±ν λͺ¨λν°λ§ μμ€ν λ°°ν¬ |
κ²μν κ²°μ λͺ¨λν°λ§ μμ€ν λ°°ν¬ |
νμ¬λ λΉμ©λ¬Έμ λ‘ μΈν΄ μλ²λ₯Ό λ΄λ Έμ΅λλ€. π API Spec (Swagger)
JWT κΈ°λ° λ‘κ·ΈμΈ κΈ°λ₯
- AccessTokenκ³Ό RefreshTokenμ νμ©ν μΈμ¦ κ΄λ¦¬
νλ‘ν μμ± λ° κ²μκΈ μμ± κΈ°λ₯
- S3 μ΄λ―Έμ§ μ λ‘λλ₯Ό ν΅ν νμΌ κ΄λ¦¬λ₯Ό ν©λλ€.
- νλ‘ν λ° κ²μκΈ λ±λ‘/μμ /μμ /μ‘°ν
- κ²μμ΄λ₯Ό ν΅ν νλ‘ν κ²μκΈ κ²μ/μμΈ μ‘°ν
- κ²μκΈμ κ²½μ° μ‘°νμ/μ’μμ/λκΈ κΈ°λ₯μ΄ μμ΄ μ΄λ₯Ό νμ©ν μΈκΈ°μ μ λ ¬μ΄ κ°λ₯ν©λλ€.
νμ λ±κΈ κ΄λ¦¬ κΈ°λ₯
- μμ½/리뷰/μ κ³ μ λ°λ₯Έ μΉ΄νμΉ΄ μ΄λ²€νΈλ₯Ό μ½μ΄ λ±κΈμ λ°μν©λλ€.
- νμ λ±κΈμ λ°λΌ κ°μ μλΉμ€ μ΄λ²€νΈμ¬λ λ°μνλ μ μκ° λ¬λΌμ§λλ€.
- μ κ³ μλΉμ€ κ²½μ°μλ νμ λ±κΈμ μκ΄μμ΄ κ°μ μ μλ‘ λ¨μ΄μ§λλ€.
μμ½/리뷰/μ κ³ κΈ°λ₯
- λμμ΄λ μμ½ νμν μ΄λΈ μμ±/μμ /μμ
- κΆν λ³ μμ½ μν μμ : μμ½ μν μμ μ λ°λ₯Έ **Kafka** μ΄λ²€νΈ λ°ν**(μλ¦Ό, μ μ , κ²°μ )
- ν΄λΉ μμ½μ λν 리뷰orμ κ³ μμ±/μμ /μμ
- μμ½/리뷰/μ κ³ μ‘°ν : λͺ¨λ λͺ©λ‘(νμ΄μ§) μ‘°νλ **Querydsl** μ νμ©ν λμ κ²μ 쿼리 μ μ©
κ²°μ κΈ°λ₯
- Toss APIλ₯Ό μ¬μ©ν κ²°μ κΈ°λ₯
- νλΆκ²°μ λ°©μμ μ΄μ©νμ¬ μλΉμ€μ μ§μ λ°λΌ κ²°μ κΈμ‘μ΄ λ¬λΌμ§λλ€.
- κ²°μ μ·¨μ μμ²μ ν΅ν μ μ°ν κ²°μ κ΄λ¦¬λ₯Ό ν μ μμ΅λλ€.
- μλΉμ€ μ 곡μ(λμμ΄λ)λ κ²°μ κ° μλ£λ 건μ λνμ¬ μ μ°λ°μ μ μμ΅λλ€.
νλ‘λͺ¨μ κΈ°λ₯
- νλ‘λͺ¨μ (μ΄λ²€νΈ)/μΏ ν° CRUD Search
- μΏ ν° λ°κΈ - Redis Lua Script μ΄μ©ν μ μ°©μ μΏ ν° μ¬κ³ λμμ± μ μ΄
- kafkaλ₯Ό μ΄μ©ν΄ μ¬μ©μ μΏ ν° λ°κΈ λΉλκΈ° μ²λ¦¬
μλ¦Ό κΈ°λ₯
- κ° μλΉμ€μμ μλ¦Ό μ΄λ²€νΈλ₯Ό μΉ΄νμΉ΄λ₯Ό ν΅ν΄ λ°νμ μ΄λ₯Ό μ½μ΄ μλ¦Όμ 보λ λλ€.
- μλ¦Ό μ‘°ν, μ½μ μ²λ¦¬
μ±ν κΈ°λ₯
- WebSocket(STOMP)λ₯Ό μ΄μ©ν μλΉμ€ μ΄μ©μ κ° μ±ν , νμ₯μ±μ κ³ λ €ν΄ kafka λΈλ‘컀 μ¬μ©
- μλ¦Ό μ‘°ν, μ½μ μ²λ¦¬
λ‘κ·Έ/μ±λ₯ λͺ¨λν°λ§
- Prometheus, Grafana, loki, zipkin μ μ΄μ©ν μλΉμ€ λ‘κ·Έ λ° μ±λ₯ λͺ¨λν°λ§
μ¬μ©μ μΈμ¦ κΈ°λ₯μ μ 곡ν©λλ€.
-
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/auth/infoμΈμ¦ μ 보 μ‘°ν POST /api/auth/loginλ‘κ·ΈμΈ POST /api/auth/sign-upνμκ°μ
μ¬μ©μ νλ‘ν μμ±, μ‘°ν, μμ , μμ κΈ°λ₯μ μ 곡ν©λλ€.
- μ¬μ©μ νλ‘ν
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/profileνλ‘ν μ 체 μ‘°ν POST /api/profileνλ‘ν μμ± GET /api/profile/myλ΄ νλ‘ν μ‘°ν GET /api/profile/{{profileId}}νΉμ νλ‘ν μ‘°ν PUT /api/profile/{{profileId}}νλ‘ν μμ POST /api/profile/{{profileId}}/awardνλ‘νμ μμ κ²½λ ₯ μΆκ° DELETE /api/profile/{{profileId}}/deleteνλ‘ν μμ DELETE /api/profile/{{profileId}}/delete/award/{{awardId}}μμ κ²½λ ₯ μμ DELETE /api/profile/{{profileId}}/delete/experience/{{workExperienceId}}κ²½λ ₯ μμ DELETE /api/profile/{{profileId}}/delete/location/{{locationId}}μμΉ μμ DELETE /api/profile/{{profileId}}/delete/price/{{priceId}}κ°κ²© μ 보 μμ DELETE /api/profile/{{profileId}}/delete/style/{{styleId}}μ€νμΌ μμ POST /api/profile/{{profileId}}/experienceκ²½λ ₯ μΆκ° POST /api/profile/{{profileId}}/locationμμΉ μΆκ° POST /api/profile/{{profileId}}/priceκ°κ²© μΆκ° POST /api/profile/{{profileId}}/styleμ€νμΌ μΆκ°
- μ μ μ 보
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ PUT /api/usersμ¬μ©μ μ 보 μμ GET /api/users/grade/myλ΄ νμ μ‘°ν GET /api/feign/user/exist/{{email}}μ΄λ©μΌλ‘ μ¬μ©μ μ‘΄μ¬ νμΈ
κ²μκΈ, λκΈ, μ’μμ, λ©ν°λ―Έλμ΄ κΈ°λ₯μ μ 곡ν©λλ€.
- κ²μκΈ
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/postsκ²μκΈ μ 체 μ‘°ν POST /api/postsκ²μκΈ μμ± GET /api/posts/searchκ²μκΈ κ²μ GET /api/posts/{{postId}}νΉμ κ²μκΈ μ‘°ν PATCH /api/posts/{{postId}}νΉμ κ²μκΈ μμ DELETE /api/posts/{{postId}}νΉμ κ²μκΈ μμ
- λκΈ & μ’μμ
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/posts/comments/searchλκΈ κ²μ GET /api/posts/comments/{{commentId}}νΉμ λκΈ μ‘°ν PATCH /api/posts/comments/{{commentId}}νΉμ λκΈ μμ DELETE /api/posts/comments/{{commentId}}νΉμ λκΈ μμ POST /api/posts/{{postId}}/commentsνΉμ κ²μκΈμ λκΈ μΆκ° POST /api/posts/{{postId}}/likeνΉμ κ²μκΈμ μ’μμ μΆκ°
- S3νμΌ UploadURL κ΄λ ¨
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/posts/{{postId}}/filesκ²μκΈ S3 UploadUrl μ‘°ν POST /api/posts/{{postId}}/filesκ²μκΈ S3 UploadUrl μΆκ° DELETE /api/posts/{{postId}}/filesκ²μκΈ S3 UploadUrl μμ
μ±ν λ°© μμ± κΈ°λ₯μ μ 곡ν©λλ€.
-
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ μμ² λ³Έλ¬Έ μ ν POST /api/chat/roomμ±ν λ°© μμ± application/json
μΏ ν° λ° νλ‘λͺ¨μ κ΄λ¦¬ κΈ°λ₯μ μ 곡ν©λλ€.
- μΏ ν°
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/my-couponsλ΄ μΏ ν° λͺ©λ‘ μ‘°ν GET /api/my-coupons/{{couponId}}νΉμ μΏ ν° μ‘°ν PATCH /api/my-coupons/{{couponId}}/useνΉμ μΏ ν° μ¬μ© μ²λ¦¬ POST /api/couponsμΏ ν° μμ± POST /api/coupons/{{couponId}}/issueνΉμ μΏ ν° λ°ν
- νλ‘λͺ¨μ
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/promotionsνλ‘λͺ¨μ λͺ©λ‘ μ‘°ν POST /api/promotionsνλ‘λͺ¨μ μμ± GET /api/promotions/{{promotionId}}νΉμ νλ‘λͺ¨μ μ‘°ν PUT /api/promotions/{{promotionId}}νΉμ νλ‘λͺ¨μ μμ DELETE /api/promotions/{{promotionId}}νΉμ νλ‘λͺ¨μ μμ
μμ½ μκ° μ¬λ‘― 리뷰, μ κ³ λ° μ¬μ©μ νκ° νλͺ© κ΄λ¦¬ κΈ°λ₯(λ΄λΆ μμ€ν )μ μ 곡ν©λλ€.
- μμ½ μκ° μ¬λ‘―
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/time-slots?startDate={{startDate}}&endDate={{endDate}}μκ° μ¬λ‘― λͺ©λ‘ μ‘°ν POST /api/time-slotsμκ° μ¬λ‘― μμ± GET /api/time-slots/{{timeSlotId}}νΉμ μκ° μ¬λ‘― μ‘°ν PUT /api/time-slots/{{timeSlotId}}μκ° μ¬λ‘― μμ DELETE /api/time-slots/{{timeSlotId}}μκ° μ¬λ‘― μμ
- μμ½
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/reservationsμμ½ λͺ©λ‘ μ‘°ν POST /api/reservationsμμ½ μμ± GET /api/reservations/{{reservationId}}νΉμ μμ½ μ‘°ν PUT /api/reservations/{{reservationId}}μμ½ μμ DELETE /api/reservations/{{reservationId}}μμ½ μμ PATCH /api/reservations/{{reservationId}}/statusμμ½ μν μμ
- 리뷰
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/reviews리뷰 λͺ©λ‘ μ‘°ν POST /api/reviews리뷰 μμ± GET /api/reviews/{{reviewId}}νΉμ 리뷰 μ‘°ν PUT /api/reviews/{{reviewId}}리뷰 μμ DELETE /api/reviews/{{reviewId}}리뷰 μμ
- μ κ³
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ POST /api/reportsμ κ³ μμ± GET /api/reports/users/{{userId}}μ¬μ©μμ λν μ κ³ μ‘°ν GET /api/reports/{{reportId}}νΉμ μ κ³ μ‘°ν DELETE /api/reports/{{reportId}}νΉμ μ κ³ μμ
- νκ°νλͺ©κ΄λ¦¬μ 보 μ‘°ν (λ΄λΆ μμ€ν
μ©)
EndPoint
λ©μλ μλν¬μΈνΈ μ€λͺ GET /api/grades/users/{{userId}}/reservations/{{reservationId}}νΉμ μμ½μ λν μ¬μ©μ νμ μ‘°ν GET /api/grades/users/{{userId}}/reviews/{{reviewId}}νΉμ 리뷰μ λν μ¬μ©μ νμ μ‘°ν
κ²°μ λ° μ μ° κ΄λ ¨ κΈ°λ₯μ μ 곡ν©λλ€.
- κ²°μ
Payment Endpoints
λ©μλ μλν¬μΈνΈ μ€λͺ POST /api/payments/toss/cancel κ²°μ νλΆ API POST /api/payments/toss TOSS κ²°μ μμ² API POST /api/payments/prepare κ²°μ μ€λΉ API GET /api/payments/toss/fail TOSS μ€ν¨ API GET /api/payments/toss/fail-cancel TOSS κ²°μ μ¬μ©μ μ·¨μ API GET /api/payments/search κ²°μ κ²μ API GET /api/payments/pending-requests κ²°μ μμ² νμΈ API GET /api/payments/myPayment λ΄ κ²°μ λͺ©λ‘ νμΈ API
- μ μ°
Settlement Endpoints
λ©μλ μλν¬μΈνΈ μ€λͺ POST /api/settlementsμλ μ μ° μμ± GET /api/settlements/details?settlementTime={{$random.integer(100)}}μ μ° μμΈ μ‘°ν GET /api/settlements/searchμ μ° κ²μ GET /api/settlements/{{settlementId}}νΉμ μ μ° μ‘°ν PATCH /api/settlements/{{settlementId}}νΉμ μ μ° μμ DELETE /api/settlements/{{settlementId}}νΉμ μ μ° μμ
- Redisμ Kafkaλ‘ κ°μ ν μ μ°©μ μΏ ν° λ°κΈ
- μμμ μ λ°μ΄νΈλ₯Ό ν΅ν μ‘°νμ, μ’μμ λμμ± μ μ΄
- λ©ν°λͺ¨λμμμ Docker λΉλ λ¬Έμ
- νλ‘ν κ²μ κΈ°λ₯ : μ€λ³΅ κ²μ
- MultipleBagFetchException λ¬Έμ
- [λΆνν μ€νΈ - νλ‘ν μ‘°ν] νλ‘ν λͺ©λ‘ μ‘°ν μ±λ₯ ν₯μ
- μ±ν μλ² λΆμ° μ²λ¦¬ - μΈμ κ΄λ¦¬