๋ณธ ์๋น์ค๋ ์ฌ์ฉ์์ ๋ ์ ์ทจํฅ์ ๊ธฐ๋ฐ์ผ๋ก ์์ ๋ก์ด ๊ฐ์ํ์ ์์ฑํ๊ณ ๊ณต์ ํ๋ ์์คํ ์ ๋๋ค.
๋ค์ด๋ฒ ๊ฒ์ API๋ก ๊ฒ์์ด๋ก ์ฑ ์ ์ง์ ๊ฒ์ํ๊ณ , ๊ฐ์ํ์ ๋ ธํธ์ ์์ฑํด ๊ทธ๋ ํ๊ธํ๊ธํ๋ ๊ฐ์์ ๊ธฐ๋กํฉ๋๋ค.
๋๋ถ์ด ์น๊ตฌ๋ค์๊ฒ ๋น๋๋ฐฉ์ธ ๋ ๋ฆฌ๋ฏ ์ฑ ๊ณผ ๋ ธํธ๋ฅผ ์นด์นด์คํก ๋ฉ์์ง๋ก ๊ณต์ ํด ์ง์์ ์ธ ๋ ์ํ๋์ ์ง์ํฉ๋๋ค.
- "์ ์ ์ฌ๋ฏธ์๊ฒ ์ฝ๋ ์ฑ
์ด ๋ญ์์ง?"
- "์ฑ
๋ณ๋ก ์งง๊ฒ ๋
ธํธ๋ฅผ ์ ์ด ๊ฐ์๋ฌธ์ ์ ๋ฆฌํด๋๊ณ ์ถ๋ค!"
- "์น๊ตฌ๋ค์ด ๊ผญ ์ฝ์ด์คฌ์ผ๋ฉด ์ข๊ฒ ๋๋ฐ... ๊ฐ์๊ณผ ํจ๊ป ์ด๋ป๊ฒ ์๋ ค์ฃผ์ง?"
- ํ๊ธํ๊ธ์์ ์ ๊ณ ๋ฏผ๋ค ์ ๋ถ ํด๊ฒฐํด๋ณด์ธ์!!!
-
application-secret.yml ํ๊ฒฝ๋ณ์ ํ์ผ ์์ฑ
ํด๋น ํ๋ก์ ํธ๋ ์๋ ํญ๋ชฉ๋ค์ด ํ๊ฒฝ๋ณ์ ํ์ผ์ ์ ๋ถ ์กด์ฌํด์ผ ํฉ๋๋ค.secret.yml
spring: data: redis: host: port: kakao: client_id: redirect_url: logout_redirect_url: #๋ฉ์ธํ์ด์ง user_base_url: kauth_base_url: user_info_url: send_base_url: send_me_url: user_friend_url: send_friends_url: jwt: access_secret_key: refresh_secret_key: share_secret_key: naver: client_id: client_secret: book_base_url: o share_book: share_base_url:
-
ํ๋ก์ ํธ ์์ ์ ๋ง๋ค์ด์ผ ํ API๋ฅผ ๋ ธ์ ๋ณด๋์ ์ ์ฒด์ ์๋น์ค๋ณ ํฐ์ผ์ผ๋ก ์์ฑํ๊ณ
-
ํ์ผ๋ง๋ค
MoSCoW
๋ฐฉ์์ผ๋ก ์ฐ์ ์์๋ฅผ ์ ํ๋ฉฐ, ํฐ์ผ๋ง๋ค ์ด์ ์์ฑํ์๊ณ -
PR ์์ฑํ ๋, ๋ณ๊ฒฝ์ฌํญ๊ณผ ํ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๊ณ ๋จธ์ง ์งํ
-
๋์ค์ฝ๋ webhook์ ํ์ฉํด PR ๊ด๋ จ ์๋ฆผ์ ํ์ธํ๊ณ ๋ค์ ์์ ์งํ
๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ
โโโ main
โย ย โโโ java
โย ย โย ย โโโ org
โย ย โย ย โโโ example
โย ย โย ย โโโ pongguel
โย ย โย ย โโโ PongguelApplication.java
โย ย โย ย โโโ book
โย ย โย ย โย ย โโโ controller
โย ย โย ย โย ย โย ย โโโ BookController.java
โย ย โย ย โย ย โย ย โโโ BookLikeController.java
โย ย โย ย โย ย โย ย โโโ BookSaveController.java
โย ย โย ย โย ย โย ย โโโ BookShareController.java
โย ย โย ย โย ย โโโ domain
โย ย โย ย โย ย โย ย โโโ Book.java
โย ย โย ย โย ย โโโ dto
โย ย โย ย โย ย โย ย โโโ BookDetailWithNoteListResponse.java
โย ย โย ย โย ย โย ย โโโ DeleteSavedBookResponse.java
โย ย โย ย โย ย โย ย โโโ LikeBookResponse.java
โย ย โย ย โย ย โย ย โโโ LikedBookListResponse.java
โย ย โย ย โย ย โย ย โโโ SaveSelectedBookResponse.java
โย ย โย ย โย ย โย ย โโโ SavedBookListResponse.java
โย ย โย ย โย ย โย ย โโโ SearchBookList.java
โย ย โย ย โย ย โย ย โโโ SearchBookRequest.java
โย ย โย ย โย ย โย ย โโโ SearchBookResponse.java
โย ย โย ย โย ย โย ย โโโ SelectedBook.java
โย ย โย ย โย ย โย ย โโโ ShareBookResponse.java
โย ย โย ย โย ย โย ย โโโ SharedBookDetailWithNoteListResponse.java
โย ย โย ย โย ย โโโ repository
โย ย โย ย โย ย โย ย โโโ BookRepository.java
โย ย โย ย โย ย โโโ service
โย ย โย ย โย ย โโโ BookService.java
โย ย โย ย โย ย โโโ LikedBookService.java
โย ย โย ย โย ย โโโ SavedBookService.java
โย ย โย ย โย ย โโโ ShareBookByKakaoTalkService.java
โย ย โย ย โย ย โโโ SharedBooksDetailService.java
โย ย โย ย โโโ config
โย ย โย ย โย ย โโโ ApiConfig.java
โย ย โย ย โย ย โโโ RedisConfig.java
โย ย โย ย โย ย โโโ SecurityConfig.java
โย ย โย ย โย ย โโโ SwaggerConfig.java
โย ย โย ย โโโ exception
โย ย โย ย โย ย โโโ BadRequestException.java
โย ย โย ย โย ย โโโ BaseException.java
โย ย โย ย โย ย โโโ ConflictException.java
โย ย โย ย โย ย โโโ ErrorCode.java
โย ย โย ย โย ย โโโ ErrorResponse.java
โย ย โย ย โย ย โโโ ForbiddenException.java
โย ย โย ย โย ย โโโ InternalServerException.java
โย ย โย ย โย ย โโโ NotFoundException.java
โย ย โย ย โย ย โโโ UnauthorizedException.java
โย ย โย ย โย ย โโโ handler
โย ย โย ย โย ย โโโ GlobalExceptionHandler.java
โย ย โย ย โโโ feign
โย ย โย ย โย ย โโโ client
โย ย โย ย โย ย โย ย โโโ SendKakaoTalkClient.java
โย ย โย ย โย ย โโโ dto
โย ย โย ย โย ย โย ย โโโ KakaoFriendsInfo.java
โย ย โย ย โย ย โย ย โโโ KakaoTalkFriendsSendRequest.java
โย ย โย ย โย ย โย ย โโโ KakaoTalkSendRequest.java
โย ย โย ย โย ย โย ย โโโ KakaoTalkSendResponse.java
โย ย โย ย โย ย โโโ service
โย ย โย ย โย ย โโโ KakaoTalkService.java
โย ย โย ย โโโ jwt
โย ย โย ย โย ย โโโ JwtAuthenticationFilter.java
โย ย โย ย โย ย โโโ JwtTokenProvider.java
โย ย โย ย โย ย โโโ JwtUtil.java
โย ย โย ย โย ย โโโ controller
โย ย โย ย โย ย โย ย โโโ JwtController.java
โย ย โย ย โย ย โโโ domain
โย ย โย ย โย ย โย ย โโโ CustomUserDetails.java
โย ย โย ย โย ย โโโ dto
โย ย โย ย โย ย โย ย โโโ JwtTokenDto.java
โย ย โย ย โย ย โย ย โโโ TokenRefreshRequest.java
โย ย โย ย โย ย โโโ service
โย ย โย ย โย ย โโโ JwtService.java
โย ย โย ย โย ย โโโ UserDetailService.java
โย ย โย ย โโโ main
โย ย โย ย โย ย โโโ controller
โย ย โย ย โย ย โย ย โโโ MainController.java
โย ย โย ย โย ย โโโ service
โย ย โย ย โโโ note
โย ย โย ย โย ย โโโ controller
โย ย โย ย โย ย โย ย โโโ NoteBookmarkController.java
โย ย โย ย โย ย โย ย โโโ NoteController.java
โย ย โย ย โย ย โย ย โโโ NoteDetailController.java
โย ย โย ย โย ย โโโ domain
โย ย โย ย โย ย โย ย โโโ Note.java
โย ย โย ย โย ย โโโ dto
โย ย โย ย โย ย โย ย โโโ BookmarkNoteResponse.java
โย ย โย ย โย ย โย ย โโโ BookmarkedNoteListResponse.java
โย ย โย ย โย ย โย ย โโโ NoteDeleteResponse.java
โย ย โย ย โย ย โย ย โโโ NoteDetailResponse.java
โย ย โย ย โย ย โย ย โโโ NoteListResponse.java
โย ย โย ย โย ย โย ย โโโ NoteWriteRequest.java
โย ย โย ย โย ย โโโ repository
โย ย โย ย โย ย โย ย โโโ NoteRepository.java
โย ย โย ย โย ย โโโ service
โย ย โย ย โย ย โโโ NoteBookmarkService.java
โย ย โย ย โย ย โโโ NoteDeleteService.java
โย ย โย ย โย ย โโโ NoteDetailService.java
โย ย โย ย โย ย โโโ NoteService.java
โย ย โย ย โโโ redis
โย ย โย ย โย ย โโโ RedisController.java
โย ย โย ย โย ย โโโ RedisParam.java
โย ย โย ย โย ย โโโ RedisRepository.java
โย ย โย ย โย ย โโโ RedisService.java
โย ย โย ย โโโ user
โย ย โย ย โโโ controller
โย ย โย ย โย ย โโโ KakaoReissueController.java
โย ย โย ย โย ย โโโ KakaoSignInController.java
โย ย โย ย โย ย โโโ KakaoSignOutController.java
โย ย โย ย โย ย โโโ UserDetailController.java
โย ย โย ย โโโ domain
โย ย โย ย โย ย โโโ KakaoToken.java
โย ย โย ย โย ย โโโ Role.java
โย ย โย ย โย ย โโโ User.java
โย ย โย ย โโโ dto
โย ย โย ย โย ย โโโ KakaoTokenInfo.java
โย ย โย ย โย ย โโโ KakaoUserInfoAndToken.java
โย ย โย ย โย ย โโโ KakaoUserInfoResponse.java
โย ย โย ย โย ย โโโ LoginResponse.java
โย ย โย ย โย ย โโโ LoginResult.java
โย ย โย ย โย ย โโโ PongUserInfo.java
โย ย โย ย โย ย โโโ UnlinkedUserDto.java
โย ย โย ย โโโ repository
โย ย โย ย โย ย โโโ KakaoTokenRepository.java
โย ย โย ย โย ย โโโ UserRepository.java
โย ย โย ย โโโ service
โย ย โย ย โโโ KakaoSignInService.java
โย ย โย ย โโโ KakaoSignOutService.java
โย ย โย ย โโโ KakaoTokenReissueService.java
โย ย โย ย โโโ UserService.java
โย ย โย ย โโโ ValidateUser.java
โย ย โโโ resources
โย ย โโโ application-secret.yml
โย ย โโโ application.yml
โย ย โโโ static
โย ย โโโ templates
โโโ test
โโโ java
โโโ org
โโโ example
โโโ pongguel
โโโ PongguelApplicationTests.java
- ์นด์นด์ค ์ด๋ฉ์ผ ์ค๋ณต์ฒดํฌ
- ํ์์ ๋ณด๊ฐ ์์ ์ ํ์๊ฐ์ ํจ๊ป ์งํ
- ๋ก๊ทธ์ธ ์ JWT(Json Web Token) ๋ฐ๊ธ -> ๋ชจ๋ API ์์ฒญ์ JWT ์ธ๊ฐ
- ์นด์นด์ค ์๋น์ค ์ ์ฒด ๋ก๊ทธ์์
- ๋ก๊ทธ์์ ์ Redis์ ์ ์ฅ๋ Refresh Token ์ญ์
- ์ฌ์ฉ์ ๋ง์ดํ์ด์ง
- ํ์ ํํด ์ ๋ชจ๋ ์ ๋ณด ์ญ์ ๋ฐ ์นด์นด์ค ์ฐ๊ฒฐ ๋๊ธฐ
- ๊ฒ์์ด๋ ์๋์ผ๋ก ์ธ์ฝ๋ฉ๋์ด ์ ๋ฌ
- ์ฑ ๊ฒ์์ ์คํ๋ง ์ํ๋ฆฌํฐ ์์ธ
- ์ฌ์ฉ์๊ฐ ์ ํํ ์ฑ ์ ISBN์ ๋ฐํ์ผ๋ก ์ฑ ์ ์์ธ์กฐํํ๊ณ DB์ ์ ์ฅ
- ์ ์ฅ๋ ์ฑ
์ข์์
๊ธฐ๋ฅ - ์ ์ฅ๋ ์ฑ
์์ธ๋ณด๊ธฐ
๊ธฐ๋ฅ (์ฑ ์ ์ ๋ณด์ ์์ฑ๋ ๋ ธํธ๋ฆฌ์คํธ ํจ๊ป ์กฐํ) - ์ ์ฅ๋ ์ฑ
๋ ธํธ
์์ฑ ๊ธฐ๋ฅ - ์ ์ฅ๋ ์ฑ
์ญ์
๊ธฐ๋ฅ, ์ฑ ๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ๋ ธํธ๋ ํจ๊ป ์ญ์ - ์ ์ฅ๋ ์ฑ
๊ณต์
๊ธฐ๋ฅ, ๊ณต์ ํ ํฐ ๋ฐ ๊ณต์ URL ์์ฑ ๋ฐ ์นด์นด์คํก ๋ฉ์์ง ์ ์ก ์ข์์
,๋ ธํธ
์ ์ฒด ๋ชฉ๋ก ์กฐํ
-
์ฌ์ฉ์์๊ฒ 10๋ถ๊ฐ ์ ํจํ ๊ณต์ ํ ํฐ ์์ฑ
-
๊ณต์ URL์ ํฌํจํด ์นด์นด์คํก ๋ฉ์์ง๋ก ์ ๋ฌ
-
๊ณต์ ๋ ์ฑ ์ URL์ ์คํ๋ง ์ํ๋ฆฌํฐ ์์ธ
-
๊ณต์ ๋ ์ฑ ์ ๋ ธํธ๋ค๋ ํจ๊ป ์ด๋ ๊ฐ๋ฅ
- ๋ ธํธ๋ ์ต์ ์์ผ๋ก ์ ๋ ฌ
- ์ ์ฅํ ์ฑ ์ ๋ํด์ ์ ํ์์ด ๋ ธํธ ์์ฑ
- ์ฌ์ฉ์๋ ๋ ธํธ ์์ , ํด์งํต ์ด๋(softDelete), ์๊ตฌ ์ญ์ , ์ฆ๊ฒจ์ฐพ๊ธฐ(๋ถ๋งํฌ) ๊ฐ๋ฅ
- ์ฆ๊ฒจ์ฐพ๊ธฐํ ๋ ธํธ๋ค ์ ์ฒด ์กฐํ (๋ณด๊ดํจ์ผ๋ก ์ด๋ํ ๋ ธํธ๋ค์ ์ ์ธ)
- ์ ์ฒด ๋ ธํธ๋ชฉ๋ก (ํ์ฑํ, ํด์งํต) ์กฐํ
- ํด์งํต์ผ๋ก ์ด๋ํ ๋ ธํธ๋ 30์ผ ๋์ ์ธ์ ๋ ์ง ํ์ฑํ ๊ฐ๋ฅ, 30์ผ ๋ค ์๊ตฌ ์ญ์
No | Title | Method | Path | Authorization |
---|---|---|---|---|
1 | ์นด์นด์ค ์ธ๊ฐ์ฝ๋ | GET |
/api/kakao/sign-in |
X |
2 | ๋ก๊ทธ์ธ ๋ฐ ํ์๊ฐ์ | GET |
/api/kakao/callback?code={์นด์นด์ค_์ธ๊ฐ์ฝ๋} |
X |
3 | ๋ก๊ทธ์์ | GET |
/api/kakao-logout/sign-out |
X |
4 | ๋ง์ดํ์ด์ง | GET |
/api/users/my-page |
O |
5 | ํ์ ํํด | GET |
/api/users/leave |
O |
6 | ์ฑ ๊ฒ์ | GET |
/api/books/search |
X |
7 | ์ฑ ์ ์ฅ | POST |
/api/books/save |
O |
8 | ๋ด ์์ฌ ์กฐํ | GET |
/api/saved-books/list |
O |
9 | ์์ฌ ์ฑ ์์ธ ์กฐํ | GET |
/api/saved-books:bookId/detail |
O |
10 | ์์ฌ ์ฑ ์ญ์ | DELETED |
/api/saved-books/:bookId/deleted |
O |
11 | ์์ฌ ์ฑ ์ข์์ | PATCH |
/api/liked-books/:bookId/like |
O |
12 | ์์ฌ ์ฑ ๋์๊ฒ ๊ณต์ ํ๊ธฐ | POST |
/api/saved-books/:bookId/share |
O |
13 | ์์ฌ ์ฑ ์น๊ตฌ์๊ฒ ๊ณต์ ํ๊ธฐ | POST |
/api/saved-books/:bookId/share-friends |
O |
14 | ์ธ๋ถ์ธ ์ฑ ์์ธ ์กฐํ | GET |
/api/shared/books/:shareToken |
O |
15 | ์ธ๋ถ์ธ ์ฑ ๋ ธํธ ์์ธ ์กฐํ | GET |
/api/shared/books/:shareToken/notes/:noteId |
O |
16 | ๋ ธํธ ์์ฑ | POST |
/api/notes/:bookId/write |
O |
17 | ๋ ธํธ ์์ธ ์กฐํ | GET |
/api/notes-detail/:noteId/read |
O |
18 | ๋ ธํธ ์์ | PATCH |
/api/notes-detail/:noteId/update |
O |
19 | ๋ ธํธ ๋ณด๊ดํจ ์ด๋ | PATCH |
/api/notes-detail/:noteId/soft-delete |
O |
20 | ๋ ธํธ ์ญ์ | DELETED |
/api/notes-detail/:noteId/final-delete |
O |
21 | ๋ ธํธ ์ฆ๊ฒจ์ฐพ๊ธฐ | PATCH |
/api/notes-detail/{noteId}/read |
O |
22 | ๋ ธํธ ์ฆ๊ฒจ์ฐพ๊ธฐ ๋ชฉ๋ก ์กฐํ | GET |
/api/bookmarked-notes/list |
O |
23 | ๋ ธํธ ํ์ฑํ ๋ชฉ๋ก ์กฐํ | GET |
/api/notes/active-list |
O |
24 | ๋ ธํธ ํด์งํต ๋ชฉ๋ก ์กฐํ | GET |
/api/notes/active-list |
O |
โก WebClient์์ JSON ์๋ต ํ์ฑ ๋ฌธ์
์นด์นด์ค API์์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ๋, JSON ์๋ต์ ํ์ฑํ๋ ๊ณผ์ ์์ get() ๋ฉ์๋ ์ฌ์ฉ ์ ๋ฌธ์ ๊ฐ ๋ฐ์
- JSON ๊ตฌ์กฐ์ ๋ณต์ก์ฑ: ์นด์นด์ค API ์๋ต์ JSON ๊ตฌ์กฐ๊ฐ ์ค์ฒฉ๋์ด ์์ด get() ๋ฉ์๋๋ก ์ง์ ์ ๊ทผํ๊ธฐ ์ด๋ ค์
- Null ๊ฐ ์ฒ๋ฆฌ: get() ๋ฉ์๋๋ ํค๊ฐ ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ ์์ธ๋ฅผ ๋ฐ์์ํฌ ์ ์์ด, ์์ ํ ์ฒ๋ฆฌ๊ฐ ํ์
-
path() ๋ฉ์๋ ์ฌ์ฉ: JSON ํธ๋ฆฌ๋ฅผ ์์ ํ๊ฒ ํ์ํ ์ ์๋ path() ๋ฉ์๋๋ก ์ ํ
-
์ค์ฒฉ๋ ๊ตฌ์กฐ ์ฒ๋ฆฌ: path().path() ํ์์ผ๋ก ์ค์ฒฉ๋ JSON ๊ตฌ์กฐ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฒ๋ฆฌ
{ Long id = jsonNode.path("id").asLong(); String email = jsonNode.path("kakao_account").path("email").asText(); String nickname = jsonNode.path("kakao_account").path("profile").path("nickname").asText(); String thumbnail_image_url = jsonNode.path("kakao_account").path("profile").path("thumbnail_image_url").asText(); }
- path() ๋ฉ์๋๋ฅผ ์ ์ ํ ์ฌ์ฉํ์ฌ JSON ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ํ์ฑ
- Null ์์ ์ฑ ํ๋ณด: path() ๋ฉ์๋๋ ํค๊ฐ ์์ ๊ฒฝ์ฐ MissingNode๋ฅผ ๋ฐํํ์ฌ NPE๋ฅผ ๋ฐฉ์ง
- ๊ธฐ๋ณธ๊ฐ ์ฒ๋ฆฌ: asText(), asLong() ๋ฑ์ ๋ฉ์๋๋ ํด๋น ๋ ธ๋๊ฐ ์๊ฑฐ๋ ๋ณํํ ์ ์๋ ๊ฒฝ์ฐ ๊ฐ๊ฐ์ ๊ธฐ๋ณธ๊ฐ(๋น ๋ฌธ์์ด, 0 ๋ฑ)์ ๋ฐํ
โก WebClient ๋ค์ด๋ฒ ์ฑ ๊ฒ์ baseUrl ์ธ์ ๋ฌธ์
WebClient์ Naver ์ฑ
๊ด๋ จ baseUrl์ ์ ์ฒด URL("https://openapi.naver.com/v1/search")์ด ์ค์ ๋์ด ์์์ง๋ง,
์ค์ ์์ฒญ ์ ์ด baseUrl์ด ์ ๋๋ก ์ธ์๋์ง ์์
- WebClient์์ baseUrl์ ์ค์ ํ์์๋ ๋ถ๊ตฌํ๊ณ , uri() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๋ ์์ ํ URI๋ฅผ ๊ตฌ์ฑํ์ง ์์ผ๋ฉด baseUrl์ด ๋ฌด์ ๊ฐ๋ฅ์ฑ ์์
- ํนํ UriBuilder๋ฅผ ์ฌ์ฉํ ๋ ์ด๋ฐ ๋ฌธ์ ๊ฐ ๋ฐ์
-
uriBuilder์ scheme("https")๋ฅผ ๋ช ์์ ์ผ๋ก ์ถ๊ฐ
-
์ค์ฒฉ๋ ๊ตฌ์กฐ ์ฒ๋ฆฌ: path().path() ํ์์ผ๋ก ์ค์ฒฉ๋ JSON ๊ตฌ์กฐ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฒ๋ฆฌ
{ .uri(uriBuilder -> uriBuilder .scheme("https") // ๋ช ์์ ์ผ๋ก scheme ์ถ๊ฐ .host(bookBasehUrl) .path("/book.json") // ... ๋๋จธ์ง ์ฝ๋ }
- ์์ ํ URL ๊ตฌ์ฑ: scheme์ ๋ช ์์ ์ผ๋ก ์ง์ ํจ์ผ๋ก์จ, ์ ์ฒด URL์ด ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑ
โก Feign JSON ์ง๋ ฌํ ๋ฌธ์ ๋ฐ ํ์ฑ ์ค๋ฅ
์ฑ
๊ณต์ ํ๊ธฐ๋ฅผ ์งํํ๋ ์ค JSON ์ง๋ ฌํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
๋๋ถ์ด ์น๊ตฌ์๊ฒ ๊ณต์ ํ๊ธฐ๋ ์ฌ์ฉ์ ์น๊ตฌ ๋ชฉ๋ก์์ ๋ถ๋ฌ์จ UUID๊ฐ reqeust์ ํ์ฑ๋์ง ์์ Bad request
๊ฐ ๊ณ์ ๋ฐ์ํ๋ค.
- JSON ์ง๋ ฌํ ๋ฌธ์ : ๊ธฐ์กด์ ์ฌ์ฉํ๋ record ํ์ ์ด Kakao API์ ์๊ตฌ์ฌํญ๊ณผ ๋ง์ง ์์๋ค.
- UUID ํ์ฑ ์ค๋ฅ: ์น๊ตฌ ๋ชฉ๋ก์ UUID๋ฅผ List ํํ๋ก ํ ๋ฒ์ ์ ์กํ๋ ๋ฐฉ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
- UUID NULL ์ธ์ ์ค๋ฅ
- JSON ์ง๋ ฌํ ๋ฌธ์
- ๊ธฐ์กด record ํ์ ์ Class ํ์์ผ๋ก ๋ค์ ๋ณ๊ฒฝ
- kakao ์๊ตฌ์ ๋ง๋๋ก ํด๋์ค ๊ตฌ์กฐ ์์
- ObjectMapper๋ฅผ ํ์ฉํด json์ผ๋ก ์ง์ ํ์ฑํด
- UUID ํ์ฑ ์ค๋ฅ
- ์น๊ตฌ ๋ชฉ๋ก UUID๋ฅผ List๋ก ํ ๋ฒ์ ์ ์กํ๋ ๋์ , ๊ฐ๋ณ์ ์ผ๋ก ๋ฐ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝ
- UUID BAD REQUEST ๋ฌธ์
- ReqeustBody์ ์์ ๋ฌธ์
- ์น๊ตฌ์๊ฒ ์ ์กํ๊ธฐ reqeust๋ ๋์๊ฒ ์ ์กํ๊ธฐ๋ฅผ ์์๋ฐ์ ์งํํ๋ค.
- ์ด ๊ณผ์ ์์ uuid ๋ฆฌ์คํธ์ contents๊ฐ ์๋ก ์์๊ฐ ๋ฐ๋์๋ค.
- feignClient์์๋ ๊ฐ๊ฐ ๋ฐ์ง ์๊ณ ํ๋์ Map์ผ๋ก ๋ฌถ์ด ์๋ต ๋ณธ๋ฌธ์ ์ ์กํ๊ณ ์์๋ค.
- ๊ณ์ํด์ uuid๊ฐ null๋ก ์ ๋ ฅ๋ผ์ ๊ฒฐ๊ตญ ํ๋์ฉ ๋ถ๋ฆฌํด param ํํ๋ก ์ ์กํ๋ค.
โก JWT ํ ํฐ ์ ํจ๊ธฐ๊ฐ ๋ง๋ฃ ์ค๋ฅ
์ก์ธ์ค ํ ํฐ ์ ํจ๊ธฐ๊ฐ ๋ง๋ฃ ์ค๋ฅ
- application-secret.yml์ ํ ํฐ๋ณ ์ ํจ๊ธฐ๊ฐ์ Long ํ์ ์ผ๋ก ์ ์ํ์ผ๋, ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ด ๊ฐ์ ๋๋ฌด ์งง๊ฒ ์ธ์ํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์
- ๋๋ถ์ด Local ํ๊ฒฝ ์๊ฐ๊ณผ JWT ํ๊ฒฝ ์๊ฐ์ ์ฐจ์ด๊ฐ ๋ฐ์ํ๋ ์ค๋ฅ๋ ๋ฐ๊ฒฌ
- ์ก์ธ์ค ํ ํฐ ๊ฒ์ฆ 30์ด ์ฌ์ ์๊ฐ์ ์ค์ ํด์คฌ์ผ๋ฉด์๋ ์ฌ์ ํ ๋ฌธ์ ๊ฐ ๋ฐ์
- ๊ฒฐ๊ตญ ํ๋ ์ฝ๋ฉ์ ์ ํจ๊ธฐ๊ฐ ์ค์
- YAML์์ Long ๋์ Integer๋ฅผ ์ฌ์ฉํ๊ธฐ
- ๋ฌธ์์ด๋ก ์ ์ํ๊ณ JAVA๋ก ํ์ฑํ๊ธฐ
jwt:
token-expiration:
access: "์ ํจ์๊ฐ"
refresh: "์ ํจ์๊ฐ"
share: "์ ํจ์๊ฐ"
@Value("${jwt.access-token-expiration}")
private String accessTokenExpirationStr;
@Value("${jwt.refresh-token-expiration}")
private String refreshTokenExpirationStr;
@Value("${jwt.share-token-expiration}")
private String shareTokenExpirationStr;
private long getAccessTokenValidity() {
return Long.parseLong(accessTokenExpirationStr);
}
private long getRefreshTokenValidity() {
return Long.parseLong(refreshTokenExpirationStr);
}
private long getShareTokenValidity() {
return Long.parseLong(shareTokenExpirationStr);
}
๐ RestTemplate์์ WebClient๋ก์ ์ ํ
๋๋ถ๋ถ RestTemplate๋ก OpenAPI ์๋ต๊ฐ์ ๋ฐ์์ค๊ณค ํ์๋ค.
ํ์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก RestTemplate์ ์๋ต๊ฐ์ ๋ฐ์์ค๋ ๋ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ์๋ ์๋ ์ ์ด ๊ฐ์ฅ ํฐ ๋ฌธ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ RestTemplate๋ Spring์์ ์ง์ ์ค๋จ์ ์๊ณ ํ๊ณ , ์๋ก์ด ๊ฐ๋ฐ์ ๋๋ถ๋ถ WebClient๋ก ๋ง์ด ๊ตฌํ๋๊ณ ์์๋ค.
ํนํ WebClient๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์คํ์ผ์ ์ง์ํด ์ฝ๋์ ๊ฐ๋
์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ์ข๋ค๊ณ ์๋ ค์ ธ ์์ด,
์๋ก์ด spring ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด๋ณด๊ณ ์ถ์๋ค!
WebClient์ ๋น๋๊ธฐ ํน์ฑ์ ํ์ฉํ๋ฉด ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์
์ ์๋ต์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์๋ค๋ ์ ์ด ๋งค๋ ฅ์ ์ด์๋ค
๋ก๊ทธ์ธ๊ณผ ์ฑ
๊ฒ์์ ๊ฒฝ์ฐ ๋น ๋ฅธ ์๋ต์ด ํ์ํ๊ธฐ์ ์ ํฉํ ๋ฐฉ์์ด๋ผ๋ ์๊ฐ์ด ๋ค์๋ค.
WebClient ๋์
์ ์ด๊ธฐ ์ค์ ์์ RestTemplate๊ณผ ์ฝ๊ฐ์ ์ฐจ์ด๊ฐ ์์๋ค.
JSON ์ธ์ฝ๋ฉ ๋ฌธ์ ๋ฅผ config ํ์ผ์ ๋ฏธ๋ฆฌ ์ค์ ํด์ผ ํ๋ค. ๋ง์ ๋ธ๋ก๊ทธ๋ค์์ ์ด์ ๊ดํด ๋ฏธ๋ฆฌ ๋ง์ํด์ฃผ์
์ ๋๋ ๋คํํ ์ด๊ธฐ ์ค์ ์ ๋ฃ์ ์ ์์๋ค.
๊ทธ๋ฆฌ๊ณ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์คํ์ผ๋ก ์ธํด ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง๊ณ ๊ฐ๋
์ฑ์ด ์ข์์ก๋ค๊ณ ๋๊ฒผ๋ค.
๋ํ ์๋ต์์ ์ํ๋ ์ ๋ณด๋ง ์ฝ๊ฒ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ์ถ์ถํ ์ ์๋ค๋ ์ ์ด ์ข์๋ค.
ํนํ ํ์์์ ๊ธฐ๋ฅ์ด ์ธ์์ ์ด์๋๋ฐ, ์ด๋ฅผ ํตํด ์ฒ๋ฆฌ ์๋๋ฅผ ๋ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์์ด ์๋น์ค ํ์ง ํฅ์์ ๋์์ด ๋ ๊ฒ์ผ๋ก ๊ธฐ๋๋๋ค!
๊ฒฐ๊ณผ์ ์ผ๋ก WebClient์ ๋น๋๊ธฐ ํน์ฑ์ ํ์ฉํจ์ผ๋ก์จ ์ ์ฒด ์๋ฒ์ ์๋ต์ด ๋ค๋ฅธ ํ๋ก์ ํธ ๋๋ณด๋ค ๋นจ๋ผ์ง์ ์ ์ ์์๋ค.
๐ ํด๋ผ์ด์ธํธ๊ฐ ์์ ๋ ์นด์นด์ค ๋ก๊ทธ์ธ ์ธ๊ฐ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ๋ฐ์์ฌ๊น?
์นด์นด์ค ๋ก๊ทธ์ธ์ ๋๋ถ๋ถ ๊ตฌํ์ ํด๋ผ์ด์ธํธ์๊ฒ์ ์ธ๊ฐ์ฝ๋๋ฅผ ๋ฐ์์ค๊ณ ,
์๋ฒ์์ ์ธ๊ฐ์ฝ๋๋ฅผ ๋ฐํ์ผ๋ก accessToken์ ๋ฐ๊ธ๋ฐ๋ ๊ฒ์ผ๋ก ์งํ๋๋ค.
ํ์ง๋ง ํ์ฌ ๋ฐฑ์๋ ๊ฐ๋ฐ๋ง ์งํํ๊ณ ์์ด์ ์ด ๋ถ๋ถ์ ์๋ฒ ํผ์์ ์ฒ๋ฆฌํ ์ ์์๊น? ๊ณ ๋ฏผํ๊ฒ ๋๋ค.
์ฐ์ , ์ธ๊ฐ์ฝ๋๋ ๋์ ์ผ๋ก ๊ณ์ ๋ณํํ๊ธฐ ๋๋ฌธ์ ์ธ๊ฐ์ฝ๋๋ฅผ param์ผ๋ก ์ฌ์ฉํ์๊ณ ์๊ฐํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฆฌ๋ค์ด๋ ํธ ๋ฐ๋ url์์ ๋ฐ๋ก ์นด์นด์ค accessToken์ ๋ฐ๊ธ๋ฐ๊ณ ํ์์ ๋ณด๊น์ง ๊ฐ์ ธ์ฌ ์ ์๋๋ก ๊ตฌํํ๊ฒ ๋๋ค!
์ด ๋ฐฉ๋ฒ์ ์ธ๋ถ์ธ ์ฑ
์ ๊ทผ์์๋ ํ์ฉํ ์ ์์๋ค. ํ์ฌ๋ Url์ ํ ํฐ๊ณผ ์ธ๊ฐ์ฝ๋๊ฐ ์ ๋ถ ๋์ค๊ธฐ ๋๋ฌธ์ ๊ฐ์ธ์ ๋ณด์ ํ ํฐ ํ์ทจ ๋ฌธ์ ๊ฐ ๊ณ ๋ฏผ๋๋ค.
๊ณต์ ํ ํฐ์ ์ํฌ๋ฆฟํค๋ฅผ ๋ฐ๋ก ๋ถ๋ฆฌํด์ฃผ๊ณ , url์๋ ๋ณด์ด์ง ์๊ฒ ํ๋ ๋ฐฉ๋ฒ์ ์ข ๋ ๊ณ ๋ฏผํด ๋ด์ผ๊ฒ ๋ค.
๐ ์นด์นด์คํก ๋ฉ์์ง ๊ณต์ ํ๊ธฐ๋ฅผ ํด๋ผ์ด์ธํธ ์์ด ๊ตฌํํ ๊น?
์ด๊ธฐ ์๊ตฌ์ฌํญ์์๋ ์นด์นด์คํก ๋ฉ์์ง ๊ณต์ ํ๊ธฐ๋ ๋ฐ๋ก ์์๋ค.
"๋์ค์ฝ๋ ์นํ
์ ์ฌ์ฉํ๋๋ฐ, ๋ด ์๋น์ค๋ ์ด๋ฐ ๊ธฐ๋ฅ์ด ์์ผ๋ฉด ์ข๊ฒ ๋๋ฐ?"์ ๋ํ ๊ณ ๋ฏผ๋ค์ด ํ๋ ๋์ค
์นด์นด์คํก ๋ก๊ทธ์ธ์ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ์นด์นด์คํก ๊ณต์ ํ๊ธฐ์ ์นด์นด์คํก ๋ฉ์์ง ์ ์กํ๊ธฐ๊ฐ ๋ ์ฌ๋๋ค.
ํด๋น API ๋ช
์ธ์๋ฅผ ํ์ธํด๋ณด๋๊น Restful ๋ฐฉ์์ ์นด์นด์คํก ๋ฉ์์ง ์ ์กํ๊ธฐ๋ง ๊ฐ๋ฅํ๋ค.
์น๊ตฌ์๊ฒ ์ฌ์ฉ์๊ฐ ์ ๋ฌํ๋ ๋ฐฉ์์ด๋, ์คํ๋ ค ์นด์นด์คํก ๋ฉ์์ง ์ ์กํ๊ธฐ๊ฐ ํ๊ธ์ ๋ ์ ๋ง๋๋ค๋ ์๊ฐ์ด ๋ค์๋ค!
- ํด๋ผ์ด์ธํธ ์์ด ์๋ฒ์์ ๊ณต์ ๋ฉ์์ง ๋ด์ฉ ๊ณ ์
- ์๋ฒ์์ ๊ณ ์ ํ ํ๋ฆฟ ์ฌ์ฉ ๋ถ๊ฐ๋ก JSON ์ง์ ํ์ฑ ํ์
- ํ ํฐ ๊ด๋ฆฌ: ์นด์นด์ค ์ก์ธ์ค ํ ํฐ ๊ด๋ฆฌ
- ์น๊ตฌ ์ ๋ณด ํ์ฉ: ์นด์นด์ค API๋ก ์ฌ์ฉ์ ์น๊ตฌ ์ ๋ณด ์กฐํ
- openFeign ๋ฐฉ์์ ํ์ฉํ๊ธฐ๋ก ํ๋ค!
- ๋ฌผ๋ก ๊ธฐ์กด webClient ๋ฐฉ์์ผ๋ก๋ ๊ฐ๋ฅํ์ง๋ง, ํจ์ฌ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง๊ณ client ์์ ์ ๋์ ํด์ฃผ๊ธฐ์ ๋ฐฑ์๋์ ๋ถ๋ด์ด ๋์๋ค.
- ์นด์นด์ค ํ ํฐ์ ์์๋ก ์๋ฒ db์ ์ ์ฅํ๋ ๋ฐฉ์์ ํํ๋ค. -> ์ถํ์ ์ค์ผ์ค๋ฌ๋ฅผ ๋๋ ค์ ๊ด๋ฆฌํด์ค ์์ ์ด๋ค.
- ๋ฉ์์ง๋ ๊ณ ์ ์ผ๋ก ์๋ฒ์์ ์์ฑํ๊ธฐ๋ก ํ๋ค. ์นด์นด์ค ๋ฉ์์ง ํ ํ๋ฆฟ์ ์ฌ์ฉํด๋ ๊ด์ฐฎ์์ง๋ง ์ฑ ํ์ง๋ฅผ ํจ๊ป ๋ณด์ฌ์ฃผ๊ณ ์ถ์ด์์๋ค!
- ๋ก์ปฌ ํ๊ฒฝ์์ ์ด๊ธฐ ํ ์คํธ ์ฑ๊ณต
๋ฉ์์ง ์ ์ก ๊ธฐ๋ฅ์ ํตํด ๋ค์ํ ๊ธฐ์ ์ ๋์ ์ ๊ทน๋ณตํ๋ฉฐ ์ค์ฉ์ ์ธ ๊ธฐ๋ฅ์ ์ฑ๊ณต์ ์ผ๋ก ๊ตฌํํ๊ฒ ๋์๋ค!
๐ ํ๋ก ํธ ํ๋ฉด์ ์ด๋ป๊ฒ ๊ตฌ์ํ ๊น?
ํ๊ธํ๊ธ ์๋น์ค๋ ์๋ก ์ฐ๊ฒฐ๋ ๊ธฐ๋ฅ๋ค์ด ๋ง์์ ์ฝ๊ฒ ๋ก์ง์ด ์ฐ๊ฒฐ๋์ง ์์๋ค.
๋๋ถ์ด ์ ๋ณด๊ฐ ๋ฑ๋ก๋์ด ์์ ๊ฒฝ์ฐ ํด๋น ๋ด์ญ๋ค๊น์ง ๋๊ธธ ํ์๊ฐ ์์๊น? ๋ผ๋ ์๊ฐ์ด ๋ค๋ฉด์ ๊ณ ๋ฏผ์ ํ๊ฒ ๋์๋ค.
์ด์ ํ๋ก์ ํธ๋ฅผ ํ ๋ ํ๋ก ํธ๋ ๊ฐ์ด ๋ง๋ค์ด๋ดค๋ ๊ฒฝํ์ ๋ฐํ์ผ๋ก ํผ๊ทธ๋ง๋ฅผ ํ์ฉํด ๊ฐ๋จํ๊ฒ UI๋ฅผ ๊ตฌ์ํ๋ค.
์ด์ ๊ฐ์ธ ํ๋ก์ ํธ ํ ๋ ํ๋ก ํธ๋ ๊ฐ์ด ๋ง๋ค์ด๋ดค๋ ๊ฒฝํ ๋๋ฌธ์ ํ๋ก ํธ๋ฅผ ๋จผ์ ์๊ฐํด๋ณด๊ณ
๋ก์ง์ ์๊ฐํ๋ ์์๋ก ๋ฐ๋ ๊ณ๊ธฐ๊ฐ ๋์๋ค. ์ด๋ ๊ฒ ์๊ฐํ๊ฒ ๋๋๊น ์ดํดํ๊ธฐ๋ ์ฝ๊ณ ๋ก์ง์ด ๋จธ๋ฆฟ์์ ๊ทธ๋ ค์ก๋ค.
์ปค๋ฐ ์ ํ
์ปค๋ฐ ์ ํ | ์๋ฏธ |
---|---|
feat | ์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ |
fix | ๋ฒ๊ทธ ์์ |
docs | ๋ฌธ์ ์์ |
style | ์ฝ๋ formatting, ์ธ๋ฏธ์ฝ๋ก ๋๋ฝ, ์ฝ๋ ์์ฒด์ ๋ณ๊ฒฝ์ด ์๋ ๊ฒฝ์ฐ |
refactor | ์ฝ๋ ๋ฆฌํฉํ ๋ง |
test | ํ ์คํธ ์ฝ๋, ๋ฆฌํฉํ ๋ง ํ ์คํธ ์ฝ๋ ์ถ๊ฐ |
chore | ํจํค์ง ๋งค๋์ ์์ , ๊ทธ ์ธ ๊ธฐํ ์์ ex) .gitignore |
์ปค๋ฐ ๋ฉ์ธ์ง ์ธ๋ถ ๋ด์ฉ
โโข ๊ธ๋ก ์์ฑํ์ฌ ๋ด์ฉ์ด ์ ์ ๋ฌ๋ ์ ์๋๋ก ํ ๊ฒ
โโข ๋ณธ๋ฌธ์๋ ๋ณ๊ฒฝํ ๋ด์ฉ๊ณผ ์ด์ ์ค๋ช (์ด๋ป๊ฒ๋ณด๋ค๋ ๋ฌด์ & ์๋ฅผ ์ค๋ช )
โ
โrefactor : ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๋ณ๊ฒฝ (title)
โ( ๊ณต ๋ฐฑ )
โ๊ธฐ์กด ๋ก๊ทธ์ธ ๋ฐฉ์์์ ~~ํ ๋ฌธ์ ๋ก ~~ํ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํ์์ต๋๋ค. (content)
โfeat : ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ
๋ธ๋ ์น ๋ช ๋ช ๊ท์น
feat/๊ธฐ๋ฅ๋ช
- ex) feat/users_apply
๋ธ๋์น ์์ฑ ๋ฐฉ๋ฒ
- ๋ธ๋์น๋ ๊ธฐ๋ฅ ๋จ์๋ก ๋๋๋ค.
- feat ๋ธ๋์น๋ dev ๋ธ๋์น์์ ํ์ํด์ ๋ง๋ ๋ค.
- PR์ ํตํด dev ๋ธ๋์น์์ ๊ธฐ๋ฅ์ด ์์ฑ๋๋ฉด main ๋ธ๋์น๋ก merge ํ๋ค.
์ด๋ฆ | ํ ์คํธ |
---|---|
main | ์ ํ์ผ๋ก ์ถ์๋ ์ ์๋ ๋ธ๋์น |
dev | ๋ค์ ์ถ์ ๋ฒ์ ์ ๊ฐ๋ฐํ๋ ๋ธ๋์น |
feat | ๊ธฐ๋ฅ์ ๊ฐ๋ฐํ๋ ๋ธ๋์น |