Skip to content

๐Ÿง ์ฝ๋‹ค ๋ฎ์–ด ๋‘” ์ข…์ด์ฑ…๋“ค, ์–ด๋””๊นŒ์ง€ ์ฝ์—ˆ๋Š”์ง€ ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”?

Notifications You must be signed in to change notification settings

yeslee-v/reading-tracker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ“š Reading Tracker

Reading Tracker Logo

์ฝ๋‹ค ๋ฎ์–ด ๋‘” ์ข…์ด์ฑ…๋“ค, ์–ด๋””๊นŒ์ง€ ์ฝ์—ˆ๋Š”์ง€ ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”?

๐Ÿ” ๋ฐฐ๊ฒฝ

  • ์ฑ…์„ ์ฝ๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด ์™„๊ฒฐ์„ ์ž˜ ๋ชปํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด์„œ ์ฝ๊ณ  ์‹ถ์€ ์ฑ…์€ ๋งŽ๋‹ค. ์ฑ…๊ฐˆํ”ผ๋งŒ ๋Š˜์–ด๋‚˜๋Š” ์ค‘..
  • ์ด๋Ÿฐ ์‹์œผ๋กœ ๋…์„œ๋ฅผ ํ•˜๋‹ค๋ณด๋‹ˆ ์–ด์ฉ” ๋• ๋‚ด๊ฐ€ ์–ด๋–ค ์ฑ…์„ ์ฝ์—ˆ๋Š”์ง€, ๋œ ์ฝ์—ˆ๋Š”์ง€ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
  • ์‹ฌ์ง€์–ด ์ฑ… ์ •๋ฆฌํ•˜๋ฉด์„œ ์ค‘๊ฐ„์— ์ฑ…๊ฐˆํ”ผ ๊ฝ‚ํžŒ๊ฑฐ๋ณด๊ณ  ์ „์— ์ด ์ฑ…์„ ์ฝ๋‹ค ๋ง์•˜๊ตฌ๋‚˜ ์‹ถ์—ˆ๋˜ ์ ๋„ ์žˆ๋‹ค.
  • ํ˜„์žฌ ๋‚ด๊ฐ€ ์–ด๋–ค ์ฑ…๋“ค์„ ์–ด๋А์ •๋„ ์ฝ์—ˆ๋Š”์ง€ ํ•œ ๋ˆˆ์— ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด?
  • eBook ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ eBook๋งŒ ์ง„๋„์œจ ํŠธ๋ž˜ํ‚นํ•  ์ˆ˜ ์žˆ๋‹ค โ†’ ๊ทธ๋Ÿผ ์ข…์ด์ฑ…์„ ๋Œ€์ƒ์œผ๋กœ ์ง„๋„์œจ์„ ์ถ”์ ํ•ด๋ณด์ž!

โœจ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” reading-tracker ๋ฐฑ์—”๋“œ API ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ

  • ๋„ค์ด๋ฒ„ ๊ณ„์ • ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ
  • ๋„ค์ด๋ฒ„ ๋„์„œ ๊ฒ€์ƒ‰ ๊ธฐ๋ฐ˜ ์ฑ… ์ถ”๊ฐ€
  • ํ˜„์žฌ ํŽ˜์ด์ง€ ์ž…๋ ฅ ์‹œ ์ž๋™ ์ง„๋„์œจ ๊ณ„์‚ฐ ๋ฐ ์ƒํƒœ ๋ณ€๊ฒฝ
  • ์ฝ๋Š”์ค‘/์™„๋ฃŒ/๋ณด๊ด€ ์ค‘์ธ ๋„์„œ ๊ฐœ์ˆ˜ ์š”์•ฝ

๊ธฐ์ˆ  ๊ธฐ๋Šฅ

  • Redis ๊ธฐ๋ฐ˜ ๋ถ„์‚ฐ๋ฝ์œผ๋กœ ๋„์„œ ์ค‘๋ณต ๋“ฑ๋ก ๋ฐฉ์ง€
  • OAuth2 ๊ธฐ๋ฐ˜ ๋กœ๊ทธ์ธ + ์ž์ฒด JWT Cookie ๋ฐœ๊ธ‰
  • Redis ์žฅ์•  ์‹œ DB fallback ์ฒ˜๋ฆฌ
  • JWT HttpOnlyยทSecure ์ฟ ํ‚ค ๊ธฐ๋ฐ˜ ์ธ์ฆ
  • ์บ์‹œ ๊ธฐ๋ฐ˜ ์„ฑ๋Šฅ ์ตœ์ ํ™”

๐Ÿ—๏ธ ์•„ํ‚คํ…์ฒ˜

graph TB
    Client[Web Client<br/>JWT Cookie]

    subgraph App[Spring Boot Application]
        Security[Security Layer]
        API[API Layer]
        Business[Business Layer]
        Data[Data Layer]
    end

    subgraph External
        NaverOAuth[Naver OAuth]
        NaverAPI[Naver Book API]
        Redis[(Redis / Redisson)]
        MySQL[(MySQL)]
    end

    Client --> Security --> API --> Business --> Data
    Security <-->|OAuth ์—ฐ๋™| NaverOAuth
    Business --> NaverAPI
    Business --> Redis
    Data --> MySQL
    style App fill: #4c6ef5, color: #fff, stroke: #364fc7, stroke-width: 3px
    style Security fill: #7950f2, color: #fff
    style API fill: #5c7cfa, color: #fff
    style Business fill: #f59f00, color: #fff
    style Data fill: #12b886, color: #fff
    style External fill: #495057, color: #fff
    style Redis fill: #ff6b6b, color: #fff
    style MySQL fill: #4dabf7, color: #fff
    style NaverAPI fill: #51cf66, color: #fff
    style NaverOAuth fill: #9775fa, color: #fff
Loading

๐Ÿงฐ ๊ธฐ์ˆ  ์Šคํƒ

  • Java 21, Spring Boot 3(Web, Security, OAuth2, JPA, Cache), RestClient
  • MySQL(RDS), Redis(ElastiCache), Redisson
  • Gradle, Docker, GitHub Actions, AWS ECR ยท EC2 ยท SSM ยท ALB

๐Ÿงช ํ…Œ์ŠคํŠธ ์ „๋žต

๋‹จ์œ„ ๊ฒ€์ฆ์€ MockMvcยทDataJpaTest๋กœ, ํ•ต์‹ฌ ์‹œ๋‚˜๋ฆฌ์˜ค SpringBootTest + Testcontainers๋กœ ํ†ตํ•ฉ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์œ„ ํ…Œ์ŠคํŠธ / ์Šฌ๋ผ์ด์Šค ํ…Œ์ŠคํŠธ

  • MockMvc ๊ธฐ๋ฐ˜ Controller ํ…Œ์ŠคํŠธ
  • @DataJpaTest ๊ธฐ๋ฐ˜ Repository/JPA ๋งคํ•‘ ๊ฒ€์ฆ
  • Service ๋‹จ์œ„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ํ…Œ์ŠคํŠธ

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ

  • Testcontainers Redis๋กœ OAuth ๋กœ๊ทธ์ธ ํ๋ฆ„ ๊ฒ€์ฆ
  • ๋„์„œ ๋“ฑ๋ก 30๊ฐœ ๋™์‹œ์„ฑ ํ™˜๊ฒฝ์—์„œ ๋ถ„์‚ฐ๋ฝ ์ฒ˜๋ฆฌ ๊ฒ€์ฆ

๐Ÿ”‘ ์ฃผ์š” API

GET /api/books?state=: ์ƒํƒœ ๊ธฐ๋ฐ˜ ๋„์„œ ๋ชฉ๋ก ๋ฐ ์ƒํƒœ๋ณ„ ํ†ต๊ณ„ ๋ฐ˜ํ™˜

Request

GET /api/books?state=IN_PROGRESS
Cookie: rt_token=eyJh...

Response

{
  "summary": {
    "inProgress": 2,
    "completed": 5,
    "archived": 1
  },
  "books": [
    {
      "id": 1,
      "title": "๋ฆฌํŒฉํ† ๋ง 2ํŒ",
      "author": "๋งˆํ‹ด ํŒŒ์šธ๋Ÿฌ",
      "publisher": "ํ•œ๋น›๋ฏธ๋””์–ด",
      "currentPage": 120,
      "totalPages": 450,
      "progress": 26,
      "state": "IN_PROGRESS"
    }
  ]
}
GET /api/books/search: ๋„ค์ด๋ฒ„ ๋„์„œ API ๊ธฐ๋ฐ˜ ๋„์„œ ๊ฒ€์ƒ‰

Request

GET /api/books/search?query=ํด๋ฆฐ%20์ฝ”๋“œ
Cookie: rt_token=eyJh...

Response

{
  "total": 1,
  "display": 1,
  "items": [
    {
      "isbn": "9788970503489",
      "title": "ํด๋ฆฐ ์ฝ”๋“œ",
      "author": "๋กœ๋ฒ„ํŠธ C. ๋งˆํ‹ด",
      "publisher": "์ธ์‚ฌ์ดํŠธ",
      "link": "https://book.naver.com/bookdb/book_detail.nhn?bid=12345"
    }
  ]
}
POST /api/books: ๊ฒ€์ƒ‰ํ•œ ๋„์„œ๋ฅผ ์‚ฌ์šฉ์ž ์„œ์žฌ์— ์ถ”๊ฐ€

Request

{
  "isbn": "9788966263158",
  "title": "ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜",
  "author": "๋กœ๋ฒ„ํŠธ C. ๋งˆํ‹ด",
  "publisher": "์ธ์‚ฌ์ดํŠธ",
  "totalPages": 400
}

Response

{
  "id": 42,
  "title": "ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜",
  "author": "๋กœ๋ฒ„ํŠธ C. ๋งˆํ‹ด",
  "publisher": "์ธ์‚ฌ์ดํŠธ",
  "state": "IN_PROGRESS",
  "currentPage": 1,
  "totalPages": 400
}

๐Ÿš€ CI/CD ํŒŒ์ดํ”„๋ผ์ธ & ๋ฐฐํฌ

๐Ÿงช ๋กœ์ปฌ ์‹คํ–‰ ๊ฐ€์ด๋“œ

export NAVER_CLIENT_ID=
export NAVER_CLIENT_SECRET=
export JWT_SECRET_KEY=

./gradlew bootRun --args='--spring.profiles.active=dev'

โš ๏ธ ๊ฐœ์„  ๋ฐฉํ–ฅ

  • ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ํ™•์žฅ: ๊ตฌ๊ธ€, ์นด์นด์˜ค
  • ๋„์„œ ๊ฒ€์ƒ‰ ํŽ˜์ด์ง€๋„ค์ด์…˜
  • ๋ชฉํ‘œ ๋ฆฌ๋งˆ์ธ๋”/ํ‘ธ์‹œ ์•Œ๋ฆผ

About

๐Ÿง ์ฝ๋‹ค ๋ฎ์–ด ๋‘” ์ข…์ด์ฑ…๋“ค, ์–ด๋””๊นŒ์ง€ ์ฝ์—ˆ๋Š”์ง€ ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”?

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published