API 잘 만들기

김재현·2022년 10월 2일
0

프로그래밍 개념

목록 보기
2/6
post-thumbnail

REST API

  • REpresentational State Transfer
    자원(Resource)을 의미(Representation)로 구분하여 그 상태를 전달
  • HTTP URI를 통해 자원을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용한다.
  • REST API는 SPA(Single Page Application) 방식으로 개발된 프론트엔드에서 백엔드의 데이터를 가져올 때 가장 많이 사용되는 자원 처리 방식이다.

특징

  • URI로 자원을 요청하여 특정 형태로 표현한다.
  • HTTP Method를 적극적으로 활용, 행위(Verb)를 나타낸다는 점.

GET /user : user의 정보를 달라는 뜻.
DELETE /user/1 : user id: 1에 해당하는 user을 제거.

  • REST API의 요청으로 나오는 응답은 대체로 JSON(Javascript Object Notation)으로 표현되므로 사람이 읽기 쉽다.

유니폼 인터페이스 (Uniform Interface)

  • URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍쳐 스타일

무상태성 (Stateless)

  • REST는 작업을 위한 상태정보를 따로 저장하고 관리하지 않는다.
  • 세션 정보, 쿠기 정보를 별도로 저장하고 관리하지 않기 때문에 API서버는 들어오는 요청만을 단순 처리 가능.
  • 서비스의 자유도가 높아지고, 서버에서 불필요한 정보를 관리하지 않으므로, 구현이 단순해진다.

캐시기능 (Cacheable)

  • HTTP 프로토콜 표준에서 사용하는 LAST-Modified 태그나 E-Tag를 이용해 캐싱 구현 가능

자체표현성 (Self Descriptiveness)

  • REST API 메시지만 이용해 그 API를 이해할 수 있는 자체 표현 구조로 표현.

클라이언트/서버 (Client/Server)

  • REST 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세선, 로그인 정보)등을 직접 관리
  • 서로의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로간 의존성 감소.

계층형 구조 (Hierachy)

  • REST 서버는 다중 계층으로 구성될 수 있으며, 보안로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고
  • Proxy, 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다.

보안

  • REST API는 무상태(Stateless) 환경에서 동작하는 것을 전제로 한다.
    따라서 보안 및 인증에 대해서는 JWT(JSON Web Token), OAuth와 같은 토큰 인증이 사용되며, 상태 유지를 위한 세션은 사용하지 않는다.
  • 보안을 위해 HTTPS를 사용하는 것을 잊어서는 안된다.
  • HTTP 요청/응답의 단순한 사이클을 거치기 때문에 프론트엔드가 어떤 환경에서 동작하는지에 대한 의존도가 낮다.
  • 자원을 자주 조회해야한다면, ETag, Last-Modified헤더를 통한 캐싱도 가능하다.
  • 이런 REST API를 설계할 때 강제되는 표준은 없지만, 보다 RESTful하게 설계하는 방법은 분명 있다. 이제부터 알아본다.

REST를 보다 RESTful하게

  • REST API를 작성할 때 핵심적인 부분은
    URI로 자원을 표현 자원에 대한 행위는 HTTP Method를 사용한다는 점.
  • 다른 부분보다 가장 우선시 해야하며, 일부는 선택적으로 제공하자.

URI 규칙

  • URI 규칙을 지켜 작성하자.

리소스 관계 표시하기

  • 자원 간 관계가 있는 경우가 있다.

http://api.test.com/users/1/posts의 경우
users/1은 많은 유저 중 ID:1인 유저를 의미하며,
posts는 해당 유저에 속한 게시글을 의미.

  • 경로에서 posts와 같이 복수형으로 쓰인 부분은 같은 계열의 여러 자원을 가지고 있는 컬렉션(Collection)이라 하고, 1과 같이 수로 쓰였거나 단수형으로 나타낸 경우 컬렉션에 포함된 자원 중 하나를 나타내는 도큐먼트(Document)라고 한다.
  • URI 준수여부에 따라 RESTful인지 구분 가능

Header 설정하기

  • 헤더를 설정하는 부분은 필수적이지는 않지만, 응답으로 돌려줄 때 프론트엔드에서 참고하기 좋다.

Content-Location

  • POST /posts{"title":"Hello,world"}와 같은 요청으로 유저를 생성했다 하자.
    Content-Location을 통해 리소스의 위치를 표현할 수 있다. 리소스 생성으로 발생한 자원의 위치는 항상 다를 것이기 때문.
  • Content-Locate: /posts/1

Content-Type

  • 서비스에 따라 xml을 제공하는 경우도 있지만, 어지간하면 json으로만 사용하여 API 사용자가 일관성 있게 사용할 수 있도록 유도하자.
  • Content-Type: application/json

Retry-After

  • API 요청을 너무 많이 한 경우 429 Too Many Requests응답과 함께 사용.
    공격자가 API 서버를 사용하여 서비스에 과부하를 일으키려 할 때 조금이나마 보호막이 될 수있지만, 이것만으로 공격을 막을 수는 없다.
  • Retry-After: 3600

HTTP 메서드 적극적으로 사용하기

  • URI 규칙과 함께 함께 가장 중요한 부분이며 지켜져야 한다.
  • REST API는 URI에 동사를 직접 명시하는 대신 HTTP Method로 무엇을 할지 명시한다. 가장 많이 사용되는 메서드는 GET, POST, PUT, DELETE이다.
  • PUT 대신 PETCH를 사용하는 경우도 있고, 완성도 높은 API 제공을 위해 추가적으로 OPTION, HEAD를 제공하기도 한다.

  • 위 표에서 PUT은 전체 자원을 수정하기 위해 사용한다.
    OPTION은 자원에 대해 사용가능한 메서드를 반환하고, HEAD는 BODY를 제외한 HEAD만 반환한다.

Form

  • Post에 대한 CRUD 작업이 있다고 생각해본다.
    이런 작업은 HTML Form을 통해 구성되는 경우가 많아 뷰와 함께 제공되는데, Form을 포함한 구성 또한 URI 규칙을 통해 RESTful 하게 구성할 수 있다.
HTTP 메서드URI설명
GET/posts모든 포스트 조회
GET/posts/create포스트 생성을 위한 Form
POST/posts포스트 생성
GET/posts/:id포스트 조회
GET/posts/:id/edit포스트를 수정하기 위한 Form
PUT/PATCH/posts/:id포스트 수정
DELETE/posts/:id포스트 삭제

HTTP 상태코드

  • 참조 블로그 참고.

REST의 3요소

구성요소내용표현방법
자원(Resource)자원HTTP URI/memvers/{1}, /member/
행위(Verb)자원에 대한 행위HTTP MethodPOST, GET, DELETE, PUT
표현(Representation)자원에 대한 행위의 내용(요청에 대한 body)HTTP Message Payload (JSON,xml 등){  member-id:”82370”,  member-name:”홍길동“,  member-org:”10100”,  member-location:”11010” }

RESTful API Design Best Practices

1. 명사를 통한 리소스 식별

  • 이해하기 쉽게 모든 리소스들에 대해 다음과 같은 구조를 적용.
    • GET /users → user 리스트 반환
    • GET /users/100 → 100 값을 갖는 user 정보 반환
    • POST /users → 신규 user 생성
    • PUT /users → 사용자 업데이트
    • DELETE /users/711 → 711 값을 갖는 유저 삭제
  • 동사를 사용해서 작성하지 않기.
    • /getAllUsers
    • /getUserByld
    • /createNewUser
    • ...

2. HTTP 헤더에 데이터 포맷 포함

  • 클라이언트와 서버 모두 통신을 위해 어떤 포맷이 사용되었는지 알아야 함.
  • 이러한 포맷은 HTTP header에 명시되어야 한다.
    • Content-Type : Request 포맷 명시
    • Accept : Acceptable한 response 포맷드의 리스트

3. GET이나 쿼리 파라미터를 통한 수정금지

  • GET 메소드를 통해 값을 변경하지 말고,
    PUT, POST, DELETE 등을 이용해 변경해야 함.
  • 즉, GET을 통해 CUD(Create, Update, Delete)를 수행하지 말 것.
    • GET /users/35/activate → 사용 금지

4. 서브 URL 표현식을 통한 세부 표현

  • API 내부에 다른 리소스와 관계가 있을 때 서브 리소스 표현을 그 관계를 표현.

5. 행위를 위한 적절한 HTTP 메서드(Vervs) 사용

  • GET
    • 리소스 조회.
    • URI 지정을 통해 리소스 정보 요청.
    • 응답 메시지의 본문에는 요청된 리소스의 세부 정보 포함.
  • POST
    • 신규 리소스 생성
    • 요청(Request) 메시지를 통해 신규 리소스 생성에 필요한 내용 전달
    • 단, POST는 실제 리소스 생성을 하지 않더라도 트리거링 하는 용도로도 사용될 수 있음.
  • PUT/PATCH
    • 기존 리소스 수정
    • 요청 메시지를 통해 리소스 수정에 필요한 내용 전달
  • DELETE
    • 리소스 삭제
    • URL에 삭제할 리소스 전달을 통해 기존 리소스 삭제

6. HTTP 응답 상태 코드 사용

  • 클라이언트가 API를 통해 서버에 요청했을 때 클라이언트는 해당 요청에 대한 실패, 처리완료 또는 잘못된 요청등에 대한 피드백을 받아야 함.
  • 응답코드는 일련의 표주화된 코드 모음으로 제공되고 있으며, RESTful 을 통한 API 호출에 적절한 HTTP 응답 코드를 리턴할 것.

7. 필드명에 대소문자 규칙 적용

  • 애플리케이션 내에서 모든 대/소문자 규칙을 따를 수 있지만, 전체에서 일관성이 유지되어야 함.
  • 요청 본문 또는 응답 유형이 JSON인 경우, 일관성을 유지하기 위해 카멜 표시법을 준수할 것.

8. 검색, 정렬, 필터링, 페이징을 위한 규칙 사용

  • 서버에 대한 요청은 하나의 데이터셋으로 처리되는 단순한 쿼리로 진행해야함.
  • GET 메소드 API로 검색, 정렬, 필터링, 페이징 등의 쿼리 매개변수 추가는 다음의 예처럼 처리 권장.

9. API 버전 관리

  • API 버전관리를 반드시 필수로 하고, 버전 API는 릴리즈 하지 말 것.
  • 간단한 서수 표현. 2.5 등과 같은 점 표기법은 자제할 것.
  • 일반적으로 버전은 v+숫자로 표기
  • /blog/api/v1
  • http://api.blog.com/v1/compa~~

참조

REST를 보다 RESTful하게 만들기
REST API 설계 가이드

0개의 댓글