REST API

REST Series

  1. REST API #1 - 이해하기
  2. REST API #2 - 디자인 가이드 (현재 글)
  3. REST API #3 - 안티 패턴

지난 포스팅에 이어, REST API 디자인 가이드에 대해 포스팅 해보겠습니다.

이전 편을 안보신 분이 있다면 위 링크에서 확인해주세요.



우린 소프트웨어 개발자로서 대부분의 시간을 REST API 를 사용하거나 구축하는데 사용하고 있습니다.

백엔드 개발자건, 안드로이드 개발자건, 프론트엔드 개발자건 다들 REST 한 API 를 사용하고 있죠.

이전 포스팅에서 우리가 사용하는 REST API 란 어떤 것이라는 걸 말씀드렸습니다.

하지만 아직 풀리지 않은 이슈가 하나 있습니다.

자 그래서 어떻게 만들라는건데?

이번 포스팅에선 그 질문에 대해 어느정도 ‘가이드’를 드리려고 합니다.


REST API 설계 원칙

1. 단순하게 만들자.

Keep It Simple Stupid Keep It Simple Stupid - KISS

API 의 기본 URL 이 단순해야 합니다. 예를 들어 제품(product)의 API 를 설계하려면 이렇게 할 수 있습니다

GET /products

GET /products/451

첫 번째 /products 는 모든 제품의 리스트를 가져오는 API고, 두 번째 /products/451 은 제품 중 451번을 가져오는 API 입니다.

URL 이 단순하지만 의미를 표현하도록 해야합니다.


2. 동사가 아니라 명사로 쓰자.

이 부분을 많은 개발자들이 실수하는 부분입니다. 일반적으로 API 에서 동사는 사용하지 않습니다.

예를 들어 유저를 등록하는 경우 많이 실수 하는 부분이 이런 부분이죠.

POST /registerUser

하지만 여기에선 동사가 (register) 사용되었습니다.

좋은 예는 아래와 같습니다.

POST /users


3.명사는 복수형으로 쓰자.

바로 위 규칙인 명사의 사용에 이어, 이번엔 ‘복수’ 명사의 사용입니다.

방금 예시를 들었던 사용자의 등록을 통해 어떻게 사용해야 하는지 간단히 알아보겠습니다.

POST /users (GOOD)

POST /user (BAD)

여기서 의문이 생길 수도 있습니다.

왜 복수형 명사를 써야해?

라는 질문이죠.

이 질문에 대한 답은 전체 사용자 리스트를 조회 하는 API 로 해보겠습니다.

GET /users
HTTP Status Code 200
Response

{
    "users": [
        {
            "idx": 29,
            "name": "kiwinam",
            "email": "kiwinam@gmail.com"
        },
        {
            "idx": 30,
            "name": "charlie",
            "email": "charlie@kiwinam.com"
        }
    ]
}

(GET /users 의 HTTP Response 예시)

/users /charlie /pets /conan
(1) (2) (3) (4)

이렇게 api가 있다면 가장 상위에 있는 1번 users 의 경우

GET /users 를 호출할 때의 API의 의미는 전체 유저들의 정보를 가져와줘 라는 의미입니다.

여기에서 중요한 건 유저의 정보를 가져오는 것이죠. 네 맞습니다. 가져오는 정보가 복수의 형태를 띄고 있죠.

그래서 복수형 명사를 사용하는 걸 권장합니다.

다른 예를 더 들어보자면

# 제품들의 정보를 가져와줘 (Response에 여러 개의 정보가 예상됨, 복수형 리소스 *products 표현)
GET /products 

# 유저들의 정보를 가져와줘 (Response에 여러 개의 정보가 예상됨, 복수형 리소스 *users 표현)
GET /users

# charlie 가 가지고 있는 펫의 정보를 가져와줘 (Response에 여러 개의 정보가 예상됨, 복수형 리소스 *pets 표현)
GET /users/charlie/pets

이렇게 여러 개 (복수 개) 의 정보들이 예상되는 요청에 맞게 복수형 리소스로 표현해줍니다.


4. HTTP 메소드를 올바르게 쓰자.

REST API 는 수행할 작업을 HTTP 메소드로 나타낼 수 있습니다.

  • GET > 리소스를 가져옵니다.

  • POST > 리소스를 새로 생성합니다.

  • PUT/PATCH > 기존 리소스의 일부 또는 전체를 업데이트합니다.

  • DELETE > 기존 자원 또는 자원 모음을 삭제합니다.

API 가 처리할 작업에 알맞는 HTTP 메소드 사용해야 합니다.


5. HTTP 응답 코드도 알맞게 쓰자.

대부분 개발자들이 HTTP Response 상태 값을 200 아니면 500만 사용합니다.

거의 모든 프로젝트가 (제가 경험한..) 급하게 개발해야하는 상황이 많아서 어느정도 이해는 가지만 그래도 좋은 습관은 아닙니다.

아래 일반적으로 사용하는 HTTP Response status code 들 입니다.

HTTP 응답 코드는 크게 5가지로 나뉩니다.

  1. 1xx (조건부 응답) - 요청을 받았고, 작업을 계속합니다. (보통 클라이언트와 서버단에선 볼 수 없는 응답 코드입니다.)

  2. 2xx (성공) - 클라이언트가 요청한 동작을 서버가 이해하고 성공적으로 처리했습니ㅏ.

  3. 3xx (리다이렉션) - 클라이언트 요청을 마치려면 추가적으로 동작을 행해야합니다.

  4. 4xx (요청 오류) - 클라이언트 요청이 잘못 되었습니다.

  5. 5xx (서버 에러) - 유효한 요청이지만, 서버가 수행하지 못했습니다.

그리고 아래는 많이 쓰는 응답 코드들입니다.

  • 200 OK - 작업이 성공함
  • 201 CREATED - POST 를 통해 리소스 생성에 성공함
  • 400 BAD REQUEST - 잘못된 요청, 서버가 요청 구문을 이해하지 못함
  • 401 UNAUTHORIZED - 권한 없음. 인증이 필요한 리소스에 접근해야 하는데, 해당 권한이 없음.
  • 403 FORBIDDEN - 서버가 요청을 거부함.
  • 404 NOT FOUND - 찾는 리소스가 없음
  • 409 TIMEOUT - 사용자의 요청과 서버의 상태가 충돌함
  • 429 TOO MANY REQUEST - 일정 시간 동안 너무 많은 요청이 들어옴
  • 500 INTERNAL SERVER ERROR - 서버에 오류가 발생해 작업을 수행할 수 없음
  • 502 BAD GATEWAY - 게이트웨이가 연결된 서버로부터 잘못된 응답을 받음

더 자세한 내용은 링크에서 확인 부탁드릴게요!


6. 버전 관리를 하자.

API 는 이전 버전과 호환되지 않지만 새로운 기능도 아닌, 이른바 한 기능의 버전이 달라지는 경우가 생깁니다.

그래서 API 의 버전 관리는 꼭 해야하는 것 중 하나입니다.

/v1/products

/v2/products

다만 여기에서 버전 리소스 명을 1.2 처럼 표시하지 마세요. 이는 자주 변경됨을 의미하고, 또한 메이저 버전의 변화가 아닌 점(dot) 이후 버전 명은 이전 버전과 호환됨을 뜻함으로 기존 버전을 유지하는 것이 맞습니다.

버전명에 대한 얘기는 이 포스팅을 보시면 도움이 될거 같아요.

https://kiwinam.com/posts/33/version-naming/


7. 페이징을 사용하자.

요즘 대세인 모바일, 그리고 인터넷 사용량이 급상승하고 있는 개도국의 경우 대량의 트래픽이 치명적일 수 있습니다.

그래서 큰 데이터를 반환할 가능성이 있는 API 는 페이징을 사용하는 것이 좋습니다.

페이징은 보통 쿼리 파라미터에 offset(여기서부터) limit(몇 개 까지 가져와줘) 으로 표현합니다.

GET /products?offset=0&limit=10

위 API 는 전체 제품 정보를 가져오는데, 0번 제품부터(offset) 10개(limit)의 제품 정보를 가져오도록 요청 했습니다.


8. Partical Response 처리하자.

위 내용과 이어지는 내용입니다.

예를 들어 하나의 API 에서 PC가 요청한 response 에는 이름, 전화번호, 이메일, 국적이 필요하다면,

동일한 API에 모바일에서 요청한 response 에는 이름, 전화번호만 필요할 수 있다는 겁니다.

이를 활용하는 기업은 페이스북이 있다고 하네요.

PC 가 요청한 경우 이름, 전화번호, 이메일, 국적이 필요함.

GET /products?offset=0&limit=10&field=name,phone,email,national

모바일에서 요청한 경우 이름과 전화번호만 필요함

GET /products?offset=0&limit=10&field=name,email


9. 에러 처리를 하자.

에러처리는 HTTP 응답 코드를 사용하고, body 에 에러에 대한 내용을 담아주는 것이 좋습니다.

그렇다 해서 모든 에러를 400 BAD REQUEST500 INTERNAL SERVER ERROR 로 응답하는 것도 지양해야겠죠.

적절한 응답 코드와 바디의 에러 메시지를 보내줘야 합니다.

예를 들어

HTTP Status Code 403 
{
    "error": {
        "message": "현재 유저는 제품 리스트를 볼 수 없는 권한입니다.",
        "code": 1002,
    }
}


여기까지 REST API 를 어떻게 디자인 해야하나? 의 질문에 답을 하기 위한 포스팅이였습니다.

조금 도움이 되셨을지 모르겠네요.

아직도 감이 잘 안잡히신다구요? 괜찮습니다. 이제 2편이니까요.

다음 편에는 REST 에서 하면 안되는, 안티 패턴 에 대해서 포스팅 하겠습니다.

긴 글 읽어 주셔서 감사합니다. 😄


연관된 글

REST Series

  1. REST API #1 - 이해하기
  2. REST API #2 - 디자인 가이드 (현재 글)
  3. REST API #3 - 안티 패턴