SlideShare a Scribd company logo
API Design &
Performance Optimization
01
API Design API Performance
API First
02 03
목차는 다음과 같습니다.
API First 전략이란 무엇인지 알아봅니다.
Restful API 디자인의 주요 원칙과 방법을 알아봅니다.
API 성능 최적화 기법을 소개합니다.
API First
API를 우선 순위에 두고 협업하는 프로세스
개발 협업 프로세스에서 `API를 우선 순위`로 두고 작업하는 것
- 다양한 실천 방법이 있지만 여기서는 api 플랫폼을 이용해 개발자, 디자이너, PO, 기획자, QA 등 여러 이해관계자가 협업하는 프로세스로 정의합니다.
Code First는 개발을 먼저 하고 코드를 통합하고 테스트를 작성하면서 api 문서를 작성하고 배포하는 방식입니다.
- 코드를 짜다가 api 수정이 필요하다고 생각되면 수정할 수 있다는 것이 장점이지만, api가 나오기 전에는 api를 기반으로 하는 작업이 지체될 수 있습니다.
API First는 api를 먼저 디자인 및 리뷰하고, api 요청과 응답을 모킹하여 디자인을 검증합니다. 이를 기반으로 개발을 진행하고, 코드를 통합 및 배포합니다.
Pros
● 변경 가능성 감소
● 병렬 작업 가능
● 통일성 확보
● 협업 촉진
● 테스팅 일원화
API First의 장점은 다음과 같습니다.
- 첫번째로는 사전 협업으로 도출된 api 디자인이기 때문에 잦은 변경 가능성을 최소화할 수 있습니다.
- 두번째로는 병렬 작업, 즉 프론트엔드에서 백엔드의 작업을 기다릴 필요 없이 동시에 작업이 가능합니다.
- 세번째로는 api 디자인 규칙과 원칙에 기반하여 설계를 진행하기 때문에 전체적으로 상태 코드, 엔드포인트 스타일 등을 통일하기가 쉽습니다.
- 네번째로는 다양한 직군간의 협업을 촉진하여 의사소통을 활성화할 수 있습니다.
- 다섯번째로는 api 플랫폼을 사용하여 프론트엔드, 백엔드 개발자 뿐만 아니라 QA, 보안팀까지 테스팅 환경을 일원화할 수 있다는 것입니다. 또한 미리 api 검증 시에 생성한 테스트셋을 개발 후에 적용하기 때문에 테스트셋
확보에도 도움이 됩니다.
Cons
● API 플랫폼 필요
○ Postman, RapidAPI, Insomnia
● 설계 복잡성
● 테스트 복잡성
한편 API First의 단점은 다음과 같습니다.
- 첫째, 이러한 프로세스를 제대로 적용하려면 api 플랫폼이 필요합니다.
- api 플랫폼이란 api 생산자와 소비자가 API를 구축, 관리, 게시 및 소비할 수 있도록 하는 통합 도구 및 프로세스를 갖춘 소프트웨어 시스템입니다.
- 잘 알려진 예로는 Postman, RapidAPI, Insomnia 등이 있습니다.
- 또한 설계 복잡성이 늘어날 수도 있습니다. 비즈니스 요구 사항, 시스템 아키텍처, api 사용자 요구 사항 등등을 고려하여 여러 이해관계자의 의견을 조율해야하기 때문입니다.
- 테스트 환경이 늘어남에 따라 테스트 복잡성이 늘어난다는 점 또한 단점이 될 수 있습니다.
API Design
API Design
● 데이터와 기능을 노출하는 방법
● 리소스 이름, 식별자, 경로 패턴, HTTP 헤더 필드 등
API 디자인이란 api가 소비자에게 데이터와 기능을 노출하는 방법에 대해 의도적으로 결정을 내리는 프로세스입니다.
- 여기에는 적절한 리소스 이름, 식별자, 경로 패턴, HTTP 헤더 필드 등을 포함합니다.
● 도큐먼트
/courses/1
● 컬렉션
/courses
● 스토어
/bookmarks, /cart-items, /favorite
● 컨트롤러
/purchase, /play
Resource
- Restful api에서 말하는 리소스는 크게 다음 세 가지를 포함합니다.
- 이 내용은 저희 플랫폼팀 내부 자료를 참고했습니다. 관심 있으신 분은 개발실 컨플루언스에서 API 디자인 검색해보시면 됩니다.
- 도큐먼트는 기본 레코드, 데이터베이스의 한 레코드입니다. 이들이 모이면 컬렉션이 됩니다.
- 컬렉션은 도큐먼트가 모인 디렉토리(폴더)의 리소스입니다. 많은 리소스를 컬렉션의 형태를 가집니다.
- 스토어는 클라이언트에서 관리하는 특별한 상태입니다. 따로 도메인 엔티티로 관리하지 않거나 임시 보관 데이터 성격이 큰 편일 경우에 스토어로 분류됩니다.
- 컨트롤러는 HTTP 메서드로 표현하기 힘든 CRUD 이외의 액션입니다. 구매하다, 재생하다 등의 사용자 정의 액션입니다.
Restful?
● /courses/123/favorite
● /clips/123/play
● /products/123/purchase
Restful api에는 엔드포인트에 동사 대신 명사를 쓰라는 원칙이 있지만, 사실 방금 보신대로 동사를 써야하는 경우도 존재합니다.
- 따라서 Restful에 얽매이지 말고 디자인하자, 는 의견도 있습니다.
이 부분은 bytebytego에서 제공한 그림입니다. 효율적이고 안전한 api를 설계하는 방법을 쇼핑카트 디자인을 사례로 들어 간단히 보여주고 있습니다. 빠르게 살펴보고 넘어가겠습니다.
- 먼저 엔드포인트에 리소스 이름을 사용해야 합니다.
- 다음은 리소스 이름에 복수를 사용하라는 것인데요. 일반적으로 컬렉션과 스토어는 복수이지만 도큐먼트는 단수를 쓴다고 합니다.
- 세번째는 멱등성입니다. POST는 원래 멱등성이 보장되지 않는 메서드인데요. 여기서는 requestId를 보내줘서 보장하고 있습니다. 멱등성이 무엇인지에 대한 내용은 뒤에서 다시 한 번 정리하겠습니다.
- 네번째는 버저닝인데요. 버전을 명시하고 이를 제일 앞에 배치하길 권장하고 있습니다.
- 다섯번째는 soft delete된 리소스를 가져올 때 쿼리스트링을 사용할 수 있다는 내용입니다.
- 여섯번째는 페이지네이션입니다. 이 부분은 api 성능최적화 부분에서 다루겠습니다.
- 다음으로 소팅과 필터링입니다. 역시 쿼리스트링을 사용할 수 있습니다.
- 보안에 관한 부분도 이후에 다루겠습니다.
- 다음은 상호 참조하는 리소스를 가져올 때 계층구조를 표현할 수 있도록 디자인하라는 내용입니다.
- 다음은 카트에 아이템을 추가할 때 쿼리스트링 대신 바디에 아이템 아이디의 uri를 넣어주는 내용입니다. 이게 어떤 내용인지 이후에 한 번 다시 다루겠습니다.
- 다음은 Rate limiting입니다. 이 부분도 곧 살펴보겠습니다.
멱등성은 요청을 반복적으로 수행할 때 같은 결과를 얻을 수 있는지의 여부입니다.
여러 번의 동일한 요청에 대한 서버측 결과가 단일 요청의 결과와 같다면 '멱등성이 보장된다'고 할 수 있습니다.
다음은 HTTP 메소드별로 멱등성이 있는지 아닌지 간략하게 보여주는 그림입니다.
- POST
- 요청별 리소스 생성
- 요청할 때마다 리소스가 생기므로 멱등성이 보장되지 않습니다.
- PATCH
- 부분 업데이트
- 장바구니 수량 업데이트 등에 사용할 경우, 요청마다 결과가 달라지므로 멱등하지 않습니다.
- 멱등하게 설계할 수도 있지만, 원래 설계 의도는 멱등성을 보장하지 않는 메서드라고 합니다.
- PUT
- 리소스 덮어쓰기에 사용됩니다.
- 멱등성이 보장됩니다.
- DELETE
- 응답 코드(상태 코드)가 달라져도 서버 측 리소스 상태는 같기 때문에 멱등합니다.
API Security
Schema Validation
Ajv, Joi
HMAC Authentication
keyed-hash message
authentication code
API 보안은 너무 방대한 주제이기 때문에 몇가지만 살짝 다루고 넘어가겠습니다.
- 가장 먼저 스키마에 따른 유효성 검사를 진행하여 잘못된 요청을 차단해야 합니다. json스키마를 많이 사용하실텐데요. 이를 이용해서 스키마 유효성을 검증해주는 ajv나 joi 같은 라이브러리들이 있습니다. fastify 같은
프레임워크에 내장되어있기도 합니다.
HMAC 인증입니다.
- HMAC은 해시 메시지 인증코드(keyed-hash message authentication code)의 준말로써 [RFC2014 표준](https://www.ietf.org/rfc/rfc2104.txt) 암호화 프로토콜입니다.
- HMAC(해시 기반 메시지 인증 코드)는 요청이 예상 소스에서 오고 있는지, 요청이 전송 중에 변조되지 않았는지 확인하는 데 사용됩니다.
- 각 메시지에 공개 키(키 식별자)와 개인 키(키-비밀)를 모두 포함하는 방식입니다. 비밀키는 서버와 클라이언트에만 알려져 있습니다.
- 쿠팡, aws 등에서 사용하고 있습니다.
HATEOAS
Hypermedia As The Engine Of Application State
REST api의 핵심이라고도 할 수 있는 HATEOAS입니다.
- 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다는 개념입니다.
- 기존에는 리소스를 특정하는 용도로 데이터베이스 외래 키(혹은 그것과 매핑되는 값)를 주로 사용합니다.
- 이렇게 하면 클라이언트는 이 값을 사용해서 URL을 구성하기 위해 API 문서를 확인해야 합니다.
- 링크 방식을 이용하면, API 공급자가 별도로 문서화하고 사용자가 학습해야 하는 정보의 양이 크게 감소합니다.
- 서버에서 URL 형식을 자유롭게 변경 가능합니다.
- 클라이언트 - 서버간 결합이 줄어듭니다.
- Google Drive, Github API 등에서 채택한 방식입니다.
- id는 self라는 키값으로 표기하고 있는데, 이는 컨벤션입니다.
● 기간 내 요청 수 제한
● 과부하, 응답 속도 지연 방지
● 악의적인 공격 방지
● 429 Too Many Requests (또는 503 Service
Unavailable)
Rate Limit
- Rate limit은 특정 기간 내 수행할 수 있는 요청 수에 제한을 설정하는 방법입니다.
- 안정성과 성능 보호를 위해 사용됩니다.
- 서버 과부하와 응답 속도 지연을 방지할 수 있습니다.
- 악의적인 공격을 방지합니다.
- 상태코드는 429 또는 503을 주로 사용합니다.
● Rules
○ Consumer (API key, IP Address)
○ Endpoint
○ Request Type (GET, POST, PUT, DELETE,
etc)
Rate Limit
- api 키나 ip 주소, 또는 엔드포인트, HTTP 메서드 등을 이용해 규칙을 정할 수 있습니다.
● WAF(Web Application Firewall)
○ Cloudfare, AWS, Akamai 등AWS WAF
● API 관리 솔루션
○ AWS API Gateway, Azure API Management,
Google Cloud Endpoints
● 애플리케이션 코드
Rate Limit
Rate Limit을 설정하는 방식은 크게 다음과 같습니다.
Rate Limit
Next.js
Next.js에서 rate limit을 설정하는 내부 코드입니다.
Github API
깃헙 api 공식 문서에서 rate limit과 관련해 제공하는 헤더입니다. 각 응답마다 해당 헤더를 확인하여 한도의 현재 상태를 확인할 수 있습니다.
- 시간당 요청수, 남은 요청수, 사용한 요청수, 요청 리밋이 리셋되는 시간, 리밋 적용 대상이 되는 리소스 정보를 제공합니다.
HTTP Status Code
https://http.cat/403
재미로 넣어본 슬라이듭니다.
URL에 HTTP 상태 코드를 입력하면 어울리는 고양이 사진을 보여줍니다. 귀엽습니다.
Datadog API Public Workspace
Datadog Public Workspace입니다.
Api 디자인을 구경하고 테스트해볼 수 있습니다. Api 플랫폼을 활용하는 방식도 엿볼 수 있습니다.
API Performance
API 성능 최적화 방법을 소개하겠습니다.
- 페이지네이션: 페이지에 순서를 매기는 것입니다. 큰 결괏값을 효율적으로 다룰 때 필요합니다.
- 비동기 로깅: 비동기적으로 로깅하고 주기적으로 디스크에 flush하여 높은 처리율을 달성하고 지연을 감소합니다.
- 여기서 언급된 링 버퍼(순환 버퍼)는 고정 큐 유형입니다. 요소를 저장하기 위해 할당된 공간을 지속적으로 재사용하는 버퍼라고 합니다.
- 캐싱: 자주 사용되는 데이터를 캐싱하는 방법입니다. 캐시 미스일 때만 디비에 접근합니다.
- 페이로드 압축: 데이터 사이즈를 줄이는 방법입니다
- 커넥션 풀: 디비 커넥션 열고 닫는 데는 많은 오버헤드가 듭니다. 커넥션 풀을 통해 커넥션을 여러 개 유지하여 애플리케이션에서 재사용할 수 있습니다.
Pagination
1. Offset
a. [GET]/api/posts?offset=0&limit=10
2. Cursor
[GET]/api/posts?cursor=eyJpZCI6MX0
1. Keyset
[GET]/api/products?last_key=XYZ123
1. Time-based
[GET]/api/events?
start_time=2023-01-01T00:00:00Z&end_time=2023-01-31T23:59:59Z
페이지네이션에도 여러 종류가 있습니다.
- 오프셋 기반 페이지네이션: 이 방법은 offset을 사용하여 각 페이지의 시작 지점을 정의하고 limit을 사용하여 페이지당 항목 수를 정의합니다.
- 가장 일반적인 페이지네이션 방식입니다.
- 페이지 기반 페이지네이션이라고도 합니다.
- 특정 페이지로 이동하여 다른 페이지에 병렬 요청을 보낼 수 있습니다.
- 구현이 쉽고, 서버측이 stateless라는 점, 플랫폼에 구애받지 않는다는 장점이 있습니다.
- 하지만 오프셋이 클수록 요청 속도가 느려지기 때문에 큰 데이터 세트에서는 성능 문제가 발생할 수 있습니다.
- 커서 기반 페이지네이션: 커서 기반 페이지네이션은 포인터(또는 커서)를 사용하여 결과를 탐색합니다. 고유 식별자 또는 토큰을 커서로 사용하여 데이터세트의 위치를 표시합니다.
- API 소비자는 데이터의 다음 페이지를 가져오기 위한 요청에 커서 값을 포함합니다.
- 서버는 일반적으로 다음페이지를 검색하기 위한 커서를 페이로드 또는 헤더에 담아 반환합니다.
- 이 접근 방식은 새 데이터가 추가되거나 기존 데이터가 수정될 때 안정성을 보장합니다.
- 커서는 타임스탬프, 기본 키 또는 레코드의 인코딩된 표현과 같은 다양한 기준을 기반으로 할 수 있습니다.
- 전체 데이터 세트가 아닌 데이터 위치 자체를 기준으로 하기 때문에 대규모 데이터 세트의 성능이 더 좋습니다.
- 하지만 구현이 복잡하고, 페이지를 건너뛸 수 없어서 원하는 페이지를 얻을 때까지 하나씩 처리해야 한다는 단점이 있습니다.
- 키 세트 페이지네이션 : Seek pagination 이라고도 합니다. 이 방법은 레코드의 정렬 순서를 설정하는 키 또는 식별자를 사용하여 결과를 페이지로 매깁니다.
- 예를 들어 데이터가 타임스탬프나 id를 기준으로 정렬된 경우 API 소비자는 마지막으로 표시된 타임스탬프나 id를 매개변수로 포함하여 다음 레코드 세트를 가져옵니다.
- 이 기술을 사용하면 기록이 중복되지 않고 후속 페이지를 효율적으로 검색할 수 있습니다.
- 구현하기가 상대적으로 쉽습니다.
- 하지만 고정값에 의존한다는 점, 특정 페이지로 이동할 수 없다는 점, 사용자 정의 정렬 순서를 설정하기 어렵다는 것 등이 단점입니다.
- 시간 기반 페이지네이션: 이 방법은 시작 또는 종료 시간을 기준으로 필터링할 때와 같이 시간 관계가 있는 데이터에 가장 적합합니다. 최신성을 기준으로 데이터를 검색할 수 있습니다.
- 항목을 건너뛰거나 간과할 가능성이 없습니다.
- 하지만 모든 항목에 타임스탬프가 있는 것은 아니기 때문에 한정적입니다.
Async Logging
동기 로깅은 모든 호출에 대해 디스크를 처리하며 시스템 속도를 저하시킬 수 있습니다. 비동기 로깅은 먼저 잠금이 없는 버퍼(lock-free buffer)에 로그를 보내고 즉시 반환합니다. 로그는 주기적으로 디스크에 플러시됩니
다. 이는 I/O 오버헤드를 크게 줄여줍니다.
- 가장 최근에 버퍼링된 로그 메시지가 손실될 가능성이 있습니다. 시스템 장애가 발생한 경우(예: 정전)
To Cache or Not to Cache
● 캐시하려는 작업이 느린가?
● 캐시가 실제로 더 빠른가?
● 캐시하려는 데이터가 동적인가?
● 데이터에 자주 액세스하는가?
● 작업에 사이드이펙트가 있는가?
언제 캐싱을 해야하는지 판단하기 위해 고려해야할 사항입니다.
- 캐시하려는 작업이 느린가?
작업 결과를 캐싱하는 것은 작업이 매우 느리거나 리소스를 많이 사용하는 경우에만 유용합니다.
느린 외부 API 또는 데이터베이스에 액세스하려고 하는지 항상 확인해야 합니다.
- 캐시가 실제로 더 빠른가?
캐시는 원본 소스보다 더 빠르게 저장하고 검색할 수 있어야 합니다. 또는 더 적은 리소스를 소비해야 합니다.
따라서 결정을 내리려면 대량의 트래픽을 시뮬레이션할 수 있는 테스트 환경을 설정하여 결과를 비교하고 성능 향상을 확인해야 합니다.
- 캐시하려는 데이터가 동적인가?
사용자가 검색어 입력하고 검색 결과를 반환하는 api처럼, 캐시된 데이터가 자주 변경되고 이를 무효화해야 하는 경우 캐싱을 통해 충분한 이점을 얻지 못할 수 있습니다.
- 데이터에 자주 액세스하는가?
데이터가 필요한 횟수가 많을수록 캐시 사용이 더 효과적입니다. 데이터 액세스에 대한 통계적 분포를 잘 이해해야 합니다.
- 원래 작업에 사이드이펙트가 있는가?
예를 들어 작업은 데이터를 저장하거나, 다른 시스템을 변경해서는 안 됩니다. 이러한 작업의 결과가 캐시되면 요청이 캐시에서 제공되고 사이드이펙트가 무시될 때 결국 애플리케이션이 중단됩니다.
주요 캐싱 전략을 소개합니다.
Cache Aside
[캐시 배제](https://www.prisma.io/dataguide/intro/database-glossary#cache-aside) 애플리케이션이 데이터를 요청하면 먼저 캐시를 확인합니다. 캐시에 데이터(캐시 적중)가 있으면 이를 반환합니다. 캐
시에 데이터가 없으면(캐시 누락) 애플리케이션이 데이터베이스를 쿼리합니다. 그런 다음 애플리케이션은 후속 쿼리를 위해 해당 데이터를 캐시에 저장합니다.
장점
- update logic이 애플리케이션 레벨에 있습니다.
- 구현이 상대적으로 쉽습니다.
단점
- 디비가 직접 업데이트된 경우 데이터가 최신이 아닐 수 있습니다.
Read Through
[캐시를 통한 읽기](https://www.prisma.io/dataguide/intro/database-glossary#read-through-caching) 캐시를 애플리케이션과 디비 중간에 둡니다.
이 전략에서 애플리케이션은 읽기를 위해 항상 캐시와 대화하며, 캐시 적중이 발생하면 데이터가 즉시 반환됩니다. 캐시 누락이 발생하는 경우 캐시는 데이터베이스에서 누락된 데이터를 채운 다음 이를 애플리케이션에 반환합니다.
모든 데이터 [쓰기](https://www.prisma.io/dataguide/intro/database-glossary#write-operation)에 대해 애플리케이션은 여전히 데이터베이스로 직접 이동합니다.
장점
- 애플리케이션 로직이 간단합니다.
- 읽기를 쉽게 확장할 수 있습니다.
단점
- 데이터 액세스 로직이 캐시에 있습니다.
- 디비 엑세스를 위한 플러그인이 필요합니다.
Write Around
-[write-around 캐싱](https://www.prisma.io/dataguide/intro/database-glossary#write-around-caching) 전략은 애플리케이션이 데이터베이스에 쓰기만을 진행합니다. 그리고 캐시에 데이터가 있으
면, 읽어옵니다. 캐시 누락이 있는 경우, 애플리케이션은 데이터베이스를 읽은 후 캐시를 업데이트합니다.
장점
- 디비가 유일한 원천입니다.
- 읽기 지연을 낮춥니다.
단점
- 쓰기 지연이 높습니다.
- 데이터가 최신이 아닐 수 있습니다.
- 이 전략은 데이터가 한 번만 기록되고 업데이트되지 않는 경우에 가장 효과적입니다.
Write Through
-[연속 쓰기 캐싱](https://www.prisma.io/dataguide/intro/database-glossary#write-through-caching) 전략은 데이터베이스에 데이터를 쓰는 대신 캐시에 씁니다. 그 다음 캐시가 즉시 데이터베이스에
기록됩니다.
장점
- 읽기 지연이 낮습니다.
- cache와 디비가 sync됩니다.
단점
- 디비 쓰기를 기다려야하기 때문에 쓰기 지연이 높습니다.
- 자주 사용되지 않는 데이터도 캐싱될 수 있습니다.
Write Back
- [Write-back](https://www.prisma.io/dataguide/intro/database-glossary#write-back-caching)은 Write-through 전략과 거의 동일하게 작동합니다. 하지만 write-back 전략에서는 애플리케
이션이 캐시에 데이터를 쓴 후에, 캐시가 데이터베이스에 즉시 쓰지 않고, 약간 딜레이 후에 씁니다.
장점
- 전반적인 쓰기 성능을 향상시킬 수 있으며 일괄 처리가 지원되는 경우 전체 쓰기도 감소합니다.
- 읽기, 쓰기 지연이 낮습니다.
- 캐시와 디비가 최종적인 일관성이 있습니다(eventual consistency).
단점
- 캐시 오류가 발생하는 경우 데이터베이스에 대한 일괄 쓰기 또는 지연된 쓰기가 아직 발생하지 않은 경우 이 지연으로 인해 데이터 손실 가능성이 열립니다.
- 자주 사용되지 않는 데이터도 캐싱될 수 있습니다.
Payload Compression
다음은 페이로드 압축입니다.
Node.js 애플리케이션에서 페이로드를 압축하는 간단한 방법을 하나 소개합니다.
Node.js 앱의 기본 파일에 있는 `compression` 미들웨어를 사용할 수 있습니다. 이렇게 하면 다양한 압축 방식을 지원하는 GZIP이 활성화됩니다. JSON 응답 및 기타 정적 파일 응답이 더 작아집니다.
- Gzip: 서버 및 클라이언트 상호작용에 가장 널리 사용되는 압축 형식입니다. Deflate 알고리즘을 기반으로 하며 현재의 모든 브라우저와 호환됩니다.
- Nginx나 Apache 같은 리버스 프록시 계층에서도 페이로드 압축을 할 수 있습니다.
Connection Pool
마지막으로 커넥션 풀입니다.
커넥션 풀은 커넥션 라이프사이클을 관리하는 역할을 합니다.
커넥션 풀은 다음과 같은 방식으로 동작합니다.
- 클라이언트가 데이터베이스에 대한 커넥션을 요청하면 커넥션 풀은 풀에 사용 가능한 커넥션이 있는지 확인합니다.
- 사용 가능한 커넥션이 있으면 클라이언트에 반환됩니다.
- 사용 가능한 커넥션이 없으면 풀은 새 커넥션을 만들어 클라이언트에 반환합니다.
- 커넥션이 사용 완료되면 재사용을 위해 풀로 다시 반환됩니다.
Thank you for Listening😊
Platform3 노서정
참고 자료
-https://github.com/ByteByteGoHq/system-design-101
-https://swagger.io/resources/articles/adopting-an-api-first-approach/
-https://www.postman.com/api-first/
-https://cleancommit.io/blog/what-is-api-first-development-and-why-is-it-important/
-https://cloud.google.com/blog/products/application-development/api-design-why-you-
should-use-links-not-keys-to-represent-relationships-in-apis?hl=en
-https://abdulrwahab.medium.com/api-architecture-performance-best-practices-for-rest-
apis-1d4a5922dae1
-https://fastcampus.atlassian.net/wiki/spaces/engineering/pages/2562916385/API
-https://www.moesif.com/blog/technical/api-design/REST-API-Design-Best-Practices-for-
Parameters-and-Query-String-Usage/
-https://restfulapi.net/idempotent-rest-apis/
-https://docs.github.com/ko/rest/overview/rate-limits-for-the-rest-api?
apiVersion=2022-11-28
-https://blog.hubspot.com/website/api-rate-limit
-https://medium.com/@amr258144/connection-pooling-in-node-js-ea4421c72dc
-https://josipmisko.com/posts/rest-api-rate-limiting
-https://www.cloudflare.com/ko-kr/learning/security/api/what-is-api-security/
-https://nordicapis.com/understanding-5-types-of-web-api-pagination/
-https://blog.coupler.io/rest-api-pagination-request/
-https://nordicapis.com/restful-api-pagination-best-practices/
-https://dev.to/pragativerma18/unlocking-the-power-of-api-pagination-best-practices-and-
strategies-4b49
-https://dev.to/dashsaurabh/5-must-ask-questions-before-you-implement-caching-1md2
-https://twitter.com/progressivecod2/status/1737011079480475968?s=12
-https://www.prisma.io/dataguide/managing-databases/introduction-database-caching
-https://www.digitalocean.com/community/tutorials/nodejs-compression

More Related Content

Similar to API Design & Performance Optimization_SlideShare.pdf (20)

PPTX
4. 대용량 아키텍쳐 설계 패턴
Terry Cho
 
PDF
제 4회 DGMIT R&D 컨퍼런스 : REST API - 리소스 지향적 아키텍처
dgmit2009
 
PDF
[강의자료]+1시간만에+끝나는+직장인+코딩+용어+해설_ver1.2.pdf
ssuser6d0da2
 
PPTX
소프트웨어 개발 트랜드 및 MSA (마이크로 서비스 아키텍쳐)의 이해
Terry Cho
 
PPTX
Restful web service
sunguen lee
 
PPTX
API 개념
Herren
 
PDF
서버학개론(백엔드 서버 개발자를 위한)
SU BO KIM
 
PDF
Rest api 테스트 수행가이드
SangIn Choung
 
PPTX
Open API 발표자료 - 김연수
Yeon Soo Kim
 
PDF
Open API - 웹 플랫폼 생태계를 만드는 기술 (2011)
Channy Yun
 
PPTX
대용량 분산 아키텍쳐 설계 #3 대용량 분산 시스템 아키텍쳐
Terry Cho
 
PDF
API Economy 시대가 온다 - 강지나 클라우드 솔루션 아키텍트
NAVER CLOUD PLATFORMㅣ네이버 클라우드 플랫폼
 
PPTX
3. 마이크로 서비스 아키텍쳐
Terry Cho
 
PPTX
Scalable web architecture and distributed systems
eva
 
PPTX
Scalable web architecture and distributed systems
현종 김
 
PPTX
Google Cloud Platform - Apigee
bliexsoft
 
PPTX
Ch6 대용량서비스레퍼런스아키텍처 part.1
Minchul Jung
 
PDF
오픈 API 서비스 A to Z: Daum API를 중심으로 (윤석찬, Daum) :: API Meetup 2014
Channy Yun
 
PPT
C++api디자인 1장
Jihoon Park
 
PDF
Massive service basic
DaeMyung Kang
 
4. 대용량 아키텍쳐 설계 패턴
Terry Cho
 
제 4회 DGMIT R&D 컨퍼런스 : REST API - 리소스 지향적 아키텍처
dgmit2009
 
[강의자료]+1시간만에+끝나는+직장인+코딩+용어+해설_ver1.2.pdf
ssuser6d0da2
 
소프트웨어 개발 트랜드 및 MSA (마이크로 서비스 아키텍쳐)의 이해
Terry Cho
 
Restful web service
sunguen lee
 
API 개념
Herren
 
서버학개론(백엔드 서버 개발자를 위한)
SU BO KIM
 
Rest api 테스트 수행가이드
SangIn Choung
 
Open API 발표자료 - 김연수
Yeon Soo Kim
 
Open API - 웹 플랫폼 생태계를 만드는 기술 (2011)
Channy Yun
 
대용량 분산 아키텍쳐 설계 #3 대용량 분산 시스템 아키텍쳐
Terry Cho
 
API Economy 시대가 온다 - 강지나 클라우드 솔루션 아키텍트
NAVER CLOUD PLATFORMㅣ네이버 클라우드 플랫폼
 
3. 마이크로 서비스 아키텍쳐
Terry Cho
 
Scalable web architecture and distributed systems
eva
 
Scalable web architecture and distributed systems
현종 김
 
Google Cloud Platform - Apigee
bliexsoft
 
Ch6 대용량서비스레퍼런스아키텍처 part.1
Minchul Jung
 
오픈 API 서비스 A to Z: Daum API를 중심으로 (윤석찬, Daum) :: API Meetup 2014
Channy Yun
 
C++api디자인 1장
Jihoon Park
 
Massive service basic
DaeMyung Kang
 

API Design & Performance Optimization_SlideShare.pdf

  • 2. 01 API Design API Performance API First 02 03 목차는 다음과 같습니다. API First 전략이란 무엇인지 알아봅니다. Restful API 디자인의 주요 원칙과 방법을 알아봅니다. API 성능 최적화 기법을 소개합니다.
  • 3. API First API를 우선 순위에 두고 협업하는 프로세스 개발 협업 프로세스에서 `API를 우선 순위`로 두고 작업하는 것 - 다양한 실천 방법이 있지만 여기서는 api 플랫폼을 이용해 개발자, 디자이너, PO, 기획자, QA 등 여러 이해관계자가 협업하는 프로세스로 정의합니다.
  • 4. Code First는 개발을 먼저 하고 코드를 통합하고 테스트를 작성하면서 api 문서를 작성하고 배포하는 방식입니다. - 코드를 짜다가 api 수정이 필요하다고 생각되면 수정할 수 있다는 것이 장점이지만, api가 나오기 전에는 api를 기반으로 하는 작업이 지체될 수 있습니다. API First는 api를 먼저 디자인 및 리뷰하고, api 요청과 응답을 모킹하여 디자인을 검증합니다. 이를 기반으로 개발을 진행하고, 코드를 통합 및 배포합니다.
  • 5. Pros ● 변경 가능성 감소 ● 병렬 작업 가능 ● 통일성 확보 ● 협업 촉진 ● 테스팅 일원화 API First의 장점은 다음과 같습니다. - 첫번째로는 사전 협업으로 도출된 api 디자인이기 때문에 잦은 변경 가능성을 최소화할 수 있습니다. - 두번째로는 병렬 작업, 즉 프론트엔드에서 백엔드의 작업을 기다릴 필요 없이 동시에 작업이 가능합니다. - 세번째로는 api 디자인 규칙과 원칙에 기반하여 설계를 진행하기 때문에 전체적으로 상태 코드, 엔드포인트 스타일 등을 통일하기가 쉽습니다. - 네번째로는 다양한 직군간의 협업을 촉진하여 의사소통을 활성화할 수 있습니다. - 다섯번째로는 api 플랫폼을 사용하여 프론트엔드, 백엔드 개발자 뿐만 아니라 QA, 보안팀까지 테스팅 환경을 일원화할 수 있다는 것입니다. 또한 미리 api 검증 시에 생성한 테스트셋을 개발 후에 적용하기 때문에 테스트셋 확보에도 도움이 됩니다.
  • 6. Cons ● API 플랫폼 필요 ○ Postman, RapidAPI, Insomnia ● 설계 복잡성 ● 테스트 복잡성 한편 API First의 단점은 다음과 같습니다. - 첫째, 이러한 프로세스를 제대로 적용하려면 api 플랫폼이 필요합니다. - api 플랫폼이란 api 생산자와 소비자가 API를 구축, 관리, 게시 및 소비할 수 있도록 하는 통합 도구 및 프로세스를 갖춘 소프트웨어 시스템입니다. - 잘 알려진 예로는 Postman, RapidAPI, Insomnia 등이 있습니다. - 또한 설계 복잡성이 늘어날 수도 있습니다. 비즈니스 요구 사항, 시스템 아키텍처, api 사용자 요구 사항 등등을 고려하여 여러 이해관계자의 의견을 조율해야하기 때문입니다. - 테스트 환경이 늘어남에 따라 테스트 복잡성이 늘어난다는 점 또한 단점이 될 수 있습니다.
  • 8. API Design ● 데이터와 기능을 노출하는 방법 ● 리소스 이름, 식별자, 경로 패턴, HTTP 헤더 필드 등 API 디자인이란 api가 소비자에게 데이터와 기능을 노출하는 방법에 대해 의도적으로 결정을 내리는 프로세스입니다. - 여기에는 적절한 리소스 이름, 식별자, 경로 패턴, HTTP 헤더 필드 등을 포함합니다.
  • 9. ● 도큐먼트 /courses/1 ● 컬렉션 /courses ● 스토어 /bookmarks, /cart-items, /favorite ● 컨트롤러 /purchase, /play Resource - Restful api에서 말하는 리소스는 크게 다음 세 가지를 포함합니다. - 이 내용은 저희 플랫폼팀 내부 자료를 참고했습니다. 관심 있으신 분은 개발실 컨플루언스에서 API 디자인 검색해보시면 됩니다. - 도큐먼트는 기본 레코드, 데이터베이스의 한 레코드입니다. 이들이 모이면 컬렉션이 됩니다. - 컬렉션은 도큐먼트가 모인 디렉토리(폴더)의 리소스입니다. 많은 리소스를 컬렉션의 형태를 가집니다. - 스토어는 클라이언트에서 관리하는 특별한 상태입니다. 따로 도메인 엔티티로 관리하지 않거나 임시 보관 데이터 성격이 큰 편일 경우에 스토어로 분류됩니다. - 컨트롤러는 HTTP 메서드로 표현하기 힘든 CRUD 이외의 액션입니다. 구매하다, 재생하다 등의 사용자 정의 액션입니다.
  • 10. Restful? ● /courses/123/favorite ● /clips/123/play ● /products/123/purchase Restful api에는 엔드포인트에 동사 대신 명사를 쓰라는 원칙이 있지만, 사실 방금 보신대로 동사를 써야하는 경우도 존재합니다. - 따라서 Restful에 얽매이지 말고 디자인하자, 는 의견도 있습니다.
  • 11. 이 부분은 bytebytego에서 제공한 그림입니다. 효율적이고 안전한 api를 설계하는 방법을 쇼핑카트 디자인을 사례로 들어 간단히 보여주고 있습니다. 빠르게 살펴보고 넘어가겠습니다. - 먼저 엔드포인트에 리소스 이름을 사용해야 합니다. - 다음은 리소스 이름에 복수를 사용하라는 것인데요. 일반적으로 컬렉션과 스토어는 복수이지만 도큐먼트는 단수를 쓴다고 합니다. - 세번째는 멱등성입니다. POST는 원래 멱등성이 보장되지 않는 메서드인데요. 여기서는 requestId를 보내줘서 보장하고 있습니다. 멱등성이 무엇인지에 대한 내용은 뒤에서 다시 한 번 정리하겠습니다. - 네번째는 버저닝인데요. 버전을 명시하고 이를 제일 앞에 배치하길 권장하고 있습니다. - 다섯번째는 soft delete된 리소스를 가져올 때 쿼리스트링을 사용할 수 있다는 내용입니다. - 여섯번째는 페이지네이션입니다. 이 부분은 api 성능최적화 부분에서 다루겠습니다. - 다음으로 소팅과 필터링입니다. 역시 쿼리스트링을 사용할 수 있습니다. - 보안에 관한 부분도 이후에 다루겠습니다. - 다음은 상호 참조하는 리소스를 가져올 때 계층구조를 표현할 수 있도록 디자인하라는 내용입니다. - 다음은 카트에 아이템을 추가할 때 쿼리스트링 대신 바디에 아이템 아이디의 uri를 넣어주는 내용입니다. 이게 어떤 내용인지 이후에 한 번 다시 다루겠습니다. - 다음은 Rate limiting입니다. 이 부분도 곧 살펴보겠습니다.
  • 12. 멱등성은 요청을 반복적으로 수행할 때 같은 결과를 얻을 수 있는지의 여부입니다. 여러 번의 동일한 요청에 대한 서버측 결과가 단일 요청의 결과와 같다면 '멱등성이 보장된다'고 할 수 있습니다. 다음은 HTTP 메소드별로 멱등성이 있는지 아닌지 간략하게 보여주는 그림입니다. - POST - 요청별 리소스 생성 - 요청할 때마다 리소스가 생기므로 멱등성이 보장되지 않습니다. - PATCH - 부분 업데이트 - 장바구니 수량 업데이트 등에 사용할 경우, 요청마다 결과가 달라지므로 멱등하지 않습니다. - 멱등하게 설계할 수도 있지만, 원래 설계 의도는 멱등성을 보장하지 않는 메서드라고 합니다. - PUT - 리소스 덮어쓰기에 사용됩니다. - 멱등성이 보장됩니다. - DELETE - 응답 코드(상태 코드)가 달라져도 서버 측 리소스 상태는 같기 때문에 멱등합니다.
  • 13. API Security Schema Validation Ajv, Joi HMAC Authentication keyed-hash message authentication code API 보안은 너무 방대한 주제이기 때문에 몇가지만 살짝 다루고 넘어가겠습니다. - 가장 먼저 스키마에 따른 유효성 검사를 진행하여 잘못된 요청을 차단해야 합니다. json스키마를 많이 사용하실텐데요. 이를 이용해서 스키마 유효성을 검증해주는 ajv나 joi 같은 라이브러리들이 있습니다. fastify 같은 프레임워크에 내장되어있기도 합니다. HMAC 인증입니다. - HMAC은 해시 메시지 인증코드(keyed-hash message authentication code)의 준말로써 [RFC2014 표준](https://www.ietf.org/rfc/rfc2104.txt) 암호화 프로토콜입니다. - HMAC(해시 기반 메시지 인증 코드)는 요청이 예상 소스에서 오고 있는지, 요청이 전송 중에 변조되지 않았는지 확인하는 데 사용됩니다. - 각 메시지에 공개 키(키 식별자)와 개인 키(키-비밀)를 모두 포함하는 방식입니다. 비밀키는 서버와 클라이언트에만 알려져 있습니다. - 쿠팡, aws 등에서 사용하고 있습니다.
  • 14. HATEOAS Hypermedia As The Engine Of Application State REST api의 핵심이라고도 할 수 있는 HATEOAS입니다. - 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다는 개념입니다. - 기존에는 리소스를 특정하는 용도로 데이터베이스 외래 키(혹은 그것과 매핑되는 값)를 주로 사용합니다. - 이렇게 하면 클라이언트는 이 값을 사용해서 URL을 구성하기 위해 API 문서를 확인해야 합니다. - 링크 방식을 이용하면, API 공급자가 별도로 문서화하고 사용자가 학습해야 하는 정보의 양이 크게 감소합니다. - 서버에서 URL 형식을 자유롭게 변경 가능합니다. - 클라이언트 - 서버간 결합이 줄어듭니다. - Google Drive, Github API 등에서 채택한 방식입니다. - id는 self라는 키값으로 표기하고 있는데, 이는 컨벤션입니다.
  • 15. ● 기간 내 요청 수 제한 ● 과부하, 응답 속도 지연 방지 ● 악의적인 공격 방지 ● 429 Too Many Requests (또는 503 Service Unavailable) Rate Limit - Rate limit은 특정 기간 내 수행할 수 있는 요청 수에 제한을 설정하는 방법입니다. - 안정성과 성능 보호를 위해 사용됩니다. - 서버 과부하와 응답 속도 지연을 방지할 수 있습니다. - 악의적인 공격을 방지합니다. - 상태코드는 429 또는 503을 주로 사용합니다.
  • 16. ● Rules ○ Consumer (API key, IP Address) ○ Endpoint ○ Request Type (GET, POST, PUT, DELETE, etc) Rate Limit - api 키나 ip 주소, 또는 엔드포인트, HTTP 메서드 등을 이용해 규칙을 정할 수 있습니다.
  • 17. ● WAF(Web Application Firewall) ○ Cloudfare, AWS, Akamai 등AWS WAF ● API 관리 솔루션 ○ AWS API Gateway, Azure API Management, Google Cloud Endpoints ● 애플리케이션 코드 Rate Limit Rate Limit을 설정하는 방식은 크게 다음과 같습니다.
  • 18. Rate Limit Next.js Next.js에서 rate limit을 설정하는 내부 코드입니다.
  • 19. Github API 깃헙 api 공식 문서에서 rate limit과 관련해 제공하는 헤더입니다. 각 응답마다 해당 헤더를 확인하여 한도의 현재 상태를 확인할 수 있습니다. - 시간당 요청수, 남은 요청수, 사용한 요청수, 요청 리밋이 리셋되는 시간, 리밋 적용 대상이 되는 리소스 정보를 제공합니다.
  • 20. HTTP Status Code https://http.cat/403 재미로 넣어본 슬라이듭니다. URL에 HTTP 상태 코드를 입력하면 어울리는 고양이 사진을 보여줍니다. 귀엽습니다.
  • 21. Datadog API Public Workspace Datadog Public Workspace입니다. Api 디자인을 구경하고 테스트해볼 수 있습니다. Api 플랫폼을 활용하는 방식도 엿볼 수 있습니다.
  • 23. API 성능 최적화 방법을 소개하겠습니다. - 페이지네이션: 페이지에 순서를 매기는 것입니다. 큰 결괏값을 효율적으로 다룰 때 필요합니다. - 비동기 로깅: 비동기적으로 로깅하고 주기적으로 디스크에 flush하여 높은 처리율을 달성하고 지연을 감소합니다. - 여기서 언급된 링 버퍼(순환 버퍼)는 고정 큐 유형입니다. 요소를 저장하기 위해 할당된 공간을 지속적으로 재사용하는 버퍼라고 합니다. - 캐싱: 자주 사용되는 데이터를 캐싱하는 방법입니다. 캐시 미스일 때만 디비에 접근합니다. - 페이로드 압축: 데이터 사이즈를 줄이는 방법입니다 - 커넥션 풀: 디비 커넥션 열고 닫는 데는 많은 오버헤드가 듭니다. 커넥션 풀을 통해 커넥션을 여러 개 유지하여 애플리케이션에서 재사용할 수 있습니다.
  • 24. Pagination 1. Offset a. [GET]/api/posts?offset=0&limit=10 2. Cursor [GET]/api/posts?cursor=eyJpZCI6MX0 1. Keyset [GET]/api/products?last_key=XYZ123 1. Time-based [GET]/api/events? start_time=2023-01-01T00:00:00Z&end_time=2023-01-31T23:59:59Z 페이지네이션에도 여러 종류가 있습니다. - 오프셋 기반 페이지네이션: 이 방법은 offset을 사용하여 각 페이지의 시작 지점을 정의하고 limit을 사용하여 페이지당 항목 수를 정의합니다. - 가장 일반적인 페이지네이션 방식입니다. - 페이지 기반 페이지네이션이라고도 합니다. - 특정 페이지로 이동하여 다른 페이지에 병렬 요청을 보낼 수 있습니다. - 구현이 쉽고, 서버측이 stateless라는 점, 플랫폼에 구애받지 않는다는 장점이 있습니다. - 하지만 오프셋이 클수록 요청 속도가 느려지기 때문에 큰 데이터 세트에서는 성능 문제가 발생할 수 있습니다. - 커서 기반 페이지네이션: 커서 기반 페이지네이션은 포인터(또는 커서)를 사용하여 결과를 탐색합니다. 고유 식별자 또는 토큰을 커서로 사용하여 데이터세트의 위치를 표시합니다. - API 소비자는 데이터의 다음 페이지를 가져오기 위한 요청에 커서 값을 포함합니다. - 서버는 일반적으로 다음페이지를 검색하기 위한 커서를 페이로드 또는 헤더에 담아 반환합니다. - 이 접근 방식은 새 데이터가 추가되거나 기존 데이터가 수정될 때 안정성을 보장합니다. - 커서는 타임스탬프, 기본 키 또는 레코드의 인코딩된 표현과 같은 다양한 기준을 기반으로 할 수 있습니다. - 전체 데이터 세트가 아닌 데이터 위치 자체를 기준으로 하기 때문에 대규모 데이터 세트의 성능이 더 좋습니다. - 하지만 구현이 복잡하고, 페이지를 건너뛸 수 없어서 원하는 페이지를 얻을 때까지 하나씩 처리해야 한다는 단점이 있습니다. - 키 세트 페이지네이션 : Seek pagination 이라고도 합니다. 이 방법은 레코드의 정렬 순서를 설정하는 키 또는 식별자를 사용하여 결과를 페이지로 매깁니다. - 예를 들어 데이터가 타임스탬프나 id를 기준으로 정렬된 경우 API 소비자는 마지막으로 표시된 타임스탬프나 id를 매개변수로 포함하여 다음 레코드 세트를 가져옵니다. - 이 기술을 사용하면 기록이 중복되지 않고 후속 페이지를 효율적으로 검색할 수 있습니다. - 구현하기가 상대적으로 쉽습니다. - 하지만 고정값에 의존한다는 점, 특정 페이지로 이동할 수 없다는 점, 사용자 정의 정렬 순서를 설정하기 어렵다는 것 등이 단점입니다. - 시간 기반 페이지네이션: 이 방법은 시작 또는 종료 시간을 기준으로 필터링할 때와 같이 시간 관계가 있는 데이터에 가장 적합합니다. 최신성을 기준으로 데이터를 검색할 수 있습니다. - 항목을 건너뛰거나 간과할 가능성이 없습니다. - 하지만 모든 항목에 타임스탬프가 있는 것은 아니기 때문에 한정적입니다.
  • 25. Async Logging 동기 로깅은 모든 호출에 대해 디스크를 처리하며 시스템 속도를 저하시킬 수 있습니다. 비동기 로깅은 먼저 잠금이 없는 버퍼(lock-free buffer)에 로그를 보내고 즉시 반환합니다. 로그는 주기적으로 디스크에 플러시됩니 다. 이는 I/O 오버헤드를 크게 줄여줍니다. - 가장 최근에 버퍼링된 로그 메시지가 손실될 가능성이 있습니다. 시스템 장애가 발생한 경우(예: 정전)
  • 26. To Cache or Not to Cache ● 캐시하려는 작업이 느린가? ● 캐시가 실제로 더 빠른가? ● 캐시하려는 데이터가 동적인가? ● 데이터에 자주 액세스하는가? ● 작업에 사이드이펙트가 있는가? 언제 캐싱을 해야하는지 판단하기 위해 고려해야할 사항입니다. - 캐시하려는 작업이 느린가? 작업 결과를 캐싱하는 것은 작업이 매우 느리거나 리소스를 많이 사용하는 경우에만 유용합니다. 느린 외부 API 또는 데이터베이스에 액세스하려고 하는지 항상 확인해야 합니다. - 캐시가 실제로 더 빠른가? 캐시는 원본 소스보다 더 빠르게 저장하고 검색할 수 있어야 합니다. 또는 더 적은 리소스를 소비해야 합니다. 따라서 결정을 내리려면 대량의 트래픽을 시뮬레이션할 수 있는 테스트 환경을 설정하여 결과를 비교하고 성능 향상을 확인해야 합니다. - 캐시하려는 데이터가 동적인가? 사용자가 검색어 입력하고 검색 결과를 반환하는 api처럼, 캐시된 데이터가 자주 변경되고 이를 무효화해야 하는 경우 캐싱을 통해 충분한 이점을 얻지 못할 수 있습니다. - 데이터에 자주 액세스하는가? 데이터가 필요한 횟수가 많을수록 캐시 사용이 더 효과적입니다. 데이터 액세스에 대한 통계적 분포를 잘 이해해야 합니다. - 원래 작업에 사이드이펙트가 있는가? 예를 들어 작업은 데이터를 저장하거나, 다른 시스템을 변경해서는 안 됩니다. 이러한 작업의 결과가 캐시되면 요청이 캐시에서 제공되고 사이드이펙트가 무시될 때 결국 애플리케이션이 중단됩니다.
  • 27. 주요 캐싱 전략을 소개합니다.
  • 28. Cache Aside [캐시 배제](https://www.prisma.io/dataguide/intro/database-glossary#cache-aside) 애플리케이션이 데이터를 요청하면 먼저 캐시를 확인합니다. 캐시에 데이터(캐시 적중)가 있으면 이를 반환합니다. 캐 시에 데이터가 없으면(캐시 누락) 애플리케이션이 데이터베이스를 쿼리합니다. 그런 다음 애플리케이션은 후속 쿼리를 위해 해당 데이터를 캐시에 저장합니다. 장점 - update logic이 애플리케이션 레벨에 있습니다. - 구현이 상대적으로 쉽습니다. 단점 - 디비가 직접 업데이트된 경우 데이터가 최신이 아닐 수 있습니다.
  • 29. Read Through [캐시를 통한 읽기](https://www.prisma.io/dataguide/intro/database-glossary#read-through-caching) 캐시를 애플리케이션과 디비 중간에 둡니다. 이 전략에서 애플리케이션은 읽기를 위해 항상 캐시와 대화하며, 캐시 적중이 발생하면 데이터가 즉시 반환됩니다. 캐시 누락이 발생하는 경우 캐시는 데이터베이스에서 누락된 데이터를 채운 다음 이를 애플리케이션에 반환합니다. 모든 데이터 [쓰기](https://www.prisma.io/dataguide/intro/database-glossary#write-operation)에 대해 애플리케이션은 여전히 데이터베이스로 직접 이동합니다. 장점 - 애플리케이션 로직이 간단합니다. - 읽기를 쉽게 확장할 수 있습니다. 단점 - 데이터 액세스 로직이 캐시에 있습니다. - 디비 엑세스를 위한 플러그인이 필요합니다.
  • 30. Write Around -[write-around 캐싱](https://www.prisma.io/dataguide/intro/database-glossary#write-around-caching) 전략은 애플리케이션이 데이터베이스에 쓰기만을 진행합니다. 그리고 캐시에 데이터가 있으 면, 읽어옵니다. 캐시 누락이 있는 경우, 애플리케이션은 데이터베이스를 읽은 후 캐시를 업데이트합니다. 장점 - 디비가 유일한 원천입니다. - 읽기 지연을 낮춥니다. 단점 - 쓰기 지연이 높습니다. - 데이터가 최신이 아닐 수 있습니다. - 이 전략은 데이터가 한 번만 기록되고 업데이트되지 않는 경우에 가장 효과적입니다.
  • 31. Write Through -[연속 쓰기 캐싱](https://www.prisma.io/dataguide/intro/database-glossary#write-through-caching) 전략은 데이터베이스에 데이터를 쓰는 대신 캐시에 씁니다. 그 다음 캐시가 즉시 데이터베이스에 기록됩니다. 장점 - 읽기 지연이 낮습니다. - cache와 디비가 sync됩니다. 단점 - 디비 쓰기를 기다려야하기 때문에 쓰기 지연이 높습니다. - 자주 사용되지 않는 데이터도 캐싱될 수 있습니다.
  • 32. Write Back - [Write-back](https://www.prisma.io/dataguide/intro/database-glossary#write-back-caching)은 Write-through 전략과 거의 동일하게 작동합니다. 하지만 write-back 전략에서는 애플리케 이션이 캐시에 데이터를 쓴 후에, 캐시가 데이터베이스에 즉시 쓰지 않고, 약간 딜레이 후에 씁니다. 장점 - 전반적인 쓰기 성능을 향상시킬 수 있으며 일괄 처리가 지원되는 경우 전체 쓰기도 감소합니다. - 읽기, 쓰기 지연이 낮습니다. - 캐시와 디비가 최종적인 일관성이 있습니다(eventual consistency). 단점 - 캐시 오류가 발생하는 경우 데이터베이스에 대한 일괄 쓰기 또는 지연된 쓰기가 아직 발생하지 않은 경우 이 지연으로 인해 데이터 손실 가능성이 열립니다. - 자주 사용되지 않는 데이터도 캐싱될 수 있습니다.
  • 33. Payload Compression 다음은 페이로드 압축입니다. Node.js 애플리케이션에서 페이로드를 압축하는 간단한 방법을 하나 소개합니다. Node.js 앱의 기본 파일에 있는 `compression` 미들웨어를 사용할 수 있습니다. 이렇게 하면 다양한 압축 방식을 지원하는 GZIP이 활성화됩니다. JSON 응답 및 기타 정적 파일 응답이 더 작아집니다. - Gzip: 서버 및 클라이언트 상호작용에 가장 널리 사용되는 압축 형식입니다. Deflate 알고리즘을 기반으로 하며 현재의 모든 브라우저와 호환됩니다. - Nginx나 Apache 같은 리버스 프록시 계층에서도 페이로드 압축을 할 수 있습니다.
  • 34. Connection Pool 마지막으로 커넥션 풀입니다. 커넥션 풀은 커넥션 라이프사이클을 관리하는 역할을 합니다. 커넥션 풀은 다음과 같은 방식으로 동작합니다. - 클라이언트가 데이터베이스에 대한 커넥션을 요청하면 커넥션 풀은 풀에 사용 가능한 커넥션이 있는지 확인합니다. - 사용 가능한 커넥션이 있으면 클라이언트에 반환됩니다. - 사용 가능한 커넥션이 없으면 풀은 새 커넥션을 만들어 클라이언트에 반환합니다. - 커넥션이 사용 완료되면 재사용을 위해 풀로 다시 반환됩니다.
  • 35. Thank you for Listening😊 Platform3 노서정
  • 36. 참고 자료 -https://github.com/ByteByteGoHq/system-design-101 -https://swagger.io/resources/articles/adopting-an-api-first-approach/ -https://www.postman.com/api-first/ -https://cleancommit.io/blog/what-is-api-first-development-and-why-is-it-important/ -https://cloud.google.com/blog/products/application-development/api-design-why-you- should-use-links-not-keys-to-represent-relationships-in-apis?hl=en -https://abdulrwahab.medium.com/api-architecture-performance-best-practices-for-rest- apis-1d4a5922dae1 -https://fastcampus.atlassian.net/wiki/spaces/engineering/pages/2562916385/API -https://www.moesif.com/blog/technical/api-design/REST-API-Design-Best-Practices-for- Parameters-and-Query-String-Usage/ -https://restfulapi.net/idempotent-rest-apis/ -https://docs.github.com/ko/rest/overview/rate-limits-for-the-rest-api? apiVersion=2022-11-28 -https://blog.hubspot.com/website/api-rate-limit -https://medium.com/@amr258144/connection-pooling-in-node-js-ea4421c72dc -https://josipmisko.com/posts/rest-api-rate-limiting -https://www.cloudflare.com/ko-kr/learning/security/api/what-is-api-security/ -https://nordicapis.com/understanding-5-types-of-web-api-pagination/ -https://blog.coupler.io/rest-api-pagination-request/ -https://nordicapis.com/restful-api-pagination-best-practices/ -https://dev.to/pragativerma18/unlocking-the-power-of-api-pagination-best-practices-and- strategies-4b49 -https://dev.to/dashsaurabh/5-must-ask-questions-before-you-implement-caching-1md2 -https://twitter.com/progressivecod2/status/1737011079480475968?s=12 -https://www.prisma.io/dataguide/managing-databases/introduction-database-caching -https://www.digitalocean.com/community/tutorials/nodejs-compression