ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RESTful API 설계
    Backend 2024. 5. 27. 15:49
    728x90

    리소스, URI

    리소스웹 상에 존재하는 이름을 가진 모든 정보를 의미합니다. url를 이용함으로써, 프로그램은 리소스가 표현하는 정보에 접근할 수 있습니다.

    URI : 유니폼 리소스 식별자, 리소스를 통일적으로 식별하는 ID

    💡 URI에는 URL, URN이 있습니다. URL은 리소스의 위치, URN은 리소스의 이름을 뜻합니다. 리소스의 이름으로 찾는 것은 거의 불가능한 일이기 때문에 거의 사용되지 않습니다. 따라서 해당 글에서는 URL과 URI를 같은 의미로 사용하겠습니다.

     

    REST

    아키텍처 스타일이란 시스템의 아키텍처를 결정할 때 나침반이 되는 것을 의미합니다.

    REST란 네트워크 시스템의 아키텍처 스타일, 즉 웹 전체의 아키텍처 스타일을 의미합니다.

     

    REST의 구성

    • 자원(Resource): URI
    • 행위(Verb) : HTTP Method
    • 표현(Representations)

    즉, REST는 URI를 통해 자원을 표시하고 HTTP Method를 이용해 자원의 행위를 규정하여 결과를 받는 것을 말합니다.

     

    REST 특징

    • 클라이언트/서버 : 유저 인터페이스와 처리를 분리
      • 웹은 HTTP라는 프로토콜을 이용해 클라이언트와 서버가 서로 통신하는 클라이언트/서버의 아키텍처 스타일을 채용하고 있습니다.
      • 즉, 클라이언트가 서버에 요청을 보내면, 서버는 클라이언트에 대해 응답을 돌려줍니다.
    • 스테이트리스 서버 : 서버 측에서 애플리케이션의 상태를 가지지 않음
      • 클라이언트의 애플리케이션의 상태를 서버에서 관리하지 않는다는 것을 의미합니다.
      • 서버 측의 구현이 간략화되고, 서버는 클라이언트로부터의 요청에 응답한 뒤 바로 서버의 자원을 해제할 수 있습니다.
    • 캐시 : 한번 가져온 리소스를 클라이언트에서 돌려쓰는 방식
      • 서버와 클라이언트 사이의 통신량을 줄여 네트워크 대역의 이용과 처리시간을 축소하고, 효율적으로 처리할 수 있다는 장점이 있습니다.
    • 유니폼 인터페이스 : URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행
      • HTTP 메서드가 고정되어 확장할 수 없는 없으므로 인터페이스의 유연성에 제약이 가함으로써 전체적인 아키텍처가 간결해집니다.
      • 인터페이스를 통일함으로써 클라이언트와 서버의 중립성이 향상됩니다.
    • 계층화 시스템 : 시스템을 계층별로 분리
      • 시스템은 여러 계층으로 구성될 수 있으며, 각 계층은 독립적인 기능을 수행함. 이러한 구조를 통해 시스템의 유연성이 증가하며, 각 계층 간의 결합도가 낮아집니다.
    • 코드 온 디맨드 : 프로그램 코드를 서버에서 다운받아 클라이언트에서 실행
      • 클라이언트를 차후에 확장할 수 있다는 장점이 있습니다.

    REST는 위의 6가지를 조합한 아키텍처 스타일입니다.

     

    REST에 기초한 아키텍처를 구축할 경우라도 REST를 구성하는 스타일 중 몇 가지를 제외하더라도 상관없습니다. 예를 들어, 쿠키를 통해 세션에 값을 저장하도록 하여 stateful하지만 URI형식은 REST의 제약에 따라는 아키텍쳐도 생각해 볼 수 있습니다. Cookie를 사용한 세션관리는 스테이트리스 서버의 이점을 버린다는 것을 이해한 후 최소한으로 이용하는 것이 좋습니다.

    만약, 대부분의 REST 스타일을 제외해야만 하는 경우에는 굳이 REST를 채용할 필요가 없습니다.

     

    리소스를 링크로 연결하여 하나의 애플리케이션을 구성한다는 개념은 REST의 근간을 이루는 사상이고, ‘접속성’이라고도 부릅니다.

    웹 서비스와 웹 API가 RESTful이 되면 웹은 전체적으로 더 좋아집니다.

    RESTful : REST의 제약에 따르고 있고, REST다운 것

    URI설계는 RESTful API의 가장 중요한 요소 중 하나로, 잘 구성된 URL은 API의 가독성과 사용성을 크게 향상시킬 수 있습니다.

     

    RESTful API 설계 원칙

    리소스 지향적 설계: RESTful API는 리소스에 기반한 설계를 통해 직관적이고 일관된 API를 제공합니다. 리소스는 URI로 식별되며, URI는 리소스를 명확하게 표현해야 합니다.

    표준 메소드 사용: HTTP 프로토콜에서 정의한 표준 메소드를 사용하여 리소스를 조작합니다. 주로 GET(조회), POST(생성), PUT(전체 수정), PATCH(부분 수정), DELETE(삭제) 등의 메소드를 사용합니다.

    상태 코드 활용: HTTP 상태 코드를 활용하여 클라이언트에게 요청의 결과를 명확하게 알려야합니다. 예를 들어, '200'은 성공, '404'는 리소스를 찾을 수 없음 등의 상태를 표현합니다.

     

    RESTful API 설계

    1. 슬래시 구분자(’/’)는 계층 관계를 나타내는 데 사용합니다.

    /blog/lee

     

    2. URI 마지막 문자로 슬래시 구분자(’/’)를 사용하지 않습니다.

    /blog/lee/ (X)
    /blog/lee (O)

     

    3. 가독성을 높이기 위해서 언더바(’_’)가 아닌 하이픈(’-’)을 사용합니다.

    /blog/lee_su (X)
    /blog/lee-su (O)
    

     

    4. URI 경로에는 소문자가 적절합니다.

    /blog/LeeLog (X)
    /blog/leelog (O)
    

     

    5. 파일 확장자는 URI에 포함하지 않습니다.

    http://example.com/blog/sangminlog/logo.jpg  (X) 
    
    GET /blog/sangminlog/logo 
    HTTP/1.1 Host: example.com Accept: image/jpg (O)

     

    6. 명사를 사용하지만, 컨트롤 자원을 의미하는 경우 동사를 허용합니다.

    /blog/sangminlog/duplicating (X)
    /blog/sangminlog/duplicate   (O)
    

     

    7. 리소스 간 연관관계가 있는 경우 아래와 같이 처리합니다.

    /리소스명/리소스id/관계가 있는 다른 리소스명

    /users/{userId}/devices
    

     

    ⇒ 구현 의존성을 배제하고 심플하게 만들면 URI가 쉽게 변경되지 않고, 사용성이 향상되며 명확하고 유지 관리가 쉬워집니다.

     

     

    HTTP 특징

    HTTP스테이트리스한 프로토콜로 설계되어 있습니다.

    Stateless란 ‘서버가 클라이언트의 애플리케이션 상태를 보존하지 않는다’는 제약을 말합니다.

     

    햄버거 가게를 예시로 들어 스테이트풀, 스테이트리스 한 대화를 살펴보겠습니다.

     

    아래는 스테이트풀한 대화입니다.

    손님 : 햄버거 세트 하나 주세요.
    점원 : 사이드메뉴는 무엇으로 하시겠습니까?
    손님 : 포테이토요.
    점원: 음료수는 무엇으로 하시겠습니까?
    손님 : 콜라요.

     

    아래는 스테이트리스한 대화입니다.

    손님: 햄버거 세트 하나 주세요.
    점원: 사이드 메뉴는 무엇으로 하시겠습니까?
    손님: 햄버거 세트와 포테이토 주세요.
    점원: 음료수는 무엇으로 하겠습니까?
    손님: 햄버거 세트에 포테이토랑 콜라로 주세요.

    스테이트풀한 대화에서 서버(점원)은 클라이언트의 이전 주문을 계속 기억하고 있다는 것을 전제로 하고있습니다.

    이런 애플리케이션 상태를 ‘세션 상태’라고도 합니다. 시스템에 로그인부터 로그아웃까지의 일력의 조작을 모아 ‘세션’이라고 부릅니다.

     

    스테이트풀 대화가 일상생활에서는 자연스럽지만, 웹으로 생각해보면 서버가 클라이언트의 애플리케이션 상태를 기억하는 것은 클라이언트 수가 많아지면 규모를 확장하기가 어렵습니다.

     

    하나의 서버가 동시에 상대할 수 있는 클라이언트 수에는 한계가 있습니다. 복수의 서버 간에 애플리케이션 상태를 동기화하고 어떤 서버라도 동일한 애플리케이션 상태를 사용할 수 있도록 해야합니다. 서버가 100대로 증가한다고 하면 데이터를 동기화시키는 오버헤드를 무시할 수 없게 됩니다.

     

    하지만 스테이트리스한 서버애플리케이션 상태를 기억할 필요가 없기 때문에 서버 시스템이 단순해집니다.

    이 특성을 이용하면 시스템을 확장시키는 것이 간단해집니다. 클라이언트가 늘어나면 서버를 단순히 증설하면 되기 때문이죠. 처리에 필요한 정보가 모두 요청에 포함되어 있으므로 클라이언트는 어느 서버로 요청을 보내도 상관없습니다.

    HTTP의 심플함은 강력한 무기입니다. HTTP가 심플하기 때문에 브라우저는 PC뿐만 아니라, 다양한 디바이스에서도 구현할 수 있게 되었습니다. 또한 심플함 덕분에 웹 서비스와 웹 API가 같은 프로토콜로 실현될 수 있습니다.

     

    HTTP 메서드

    HTTP 메서드는 8개로 이루어져 있습니다.

    메서드 의미
    GET 리소스 취득
    POST 서브 리소스 작성, 리소스 데이터 추가 등
    PUT 리소스 갱신, 작성
    DELETE 리소스 삭제
    HEAD 리소스 헤더 취득
    OPIONS 리소스가 서포트하는 메서드 취득
    TRACE 요청 메시지를 반환 시험
    CONNECT 프록시 동작의 터널 접속으로 변경

    이 중에서 TRACE, CONNECT는 거의 사용하지 않고 나머지 6개를 주로 사용합니다.

     

    PUT, POST 둘다 리소스를 작성할 수 있습니다.

    POST로 리소스를 작성하면 클라이언트는 리소스의 URI를 지정할 수 없고, URI의 결정권은 서버에 있습니다. 반대로, PUT으로 리소스를 작성하면 리소스의 URI는 클라이언트가 결정합니다.

    특별한 이유가 없는 한, 리소스의 작성은 POST로 수행하여 URI를 서버 측에서 결정하는 설계가 바람직합니다.

     

    통신 에러가 발생했을 시, 요청을 어떻게 회복할 것인지는 HTTP의 중대한 과제입니다. HTTP 스펙에는 프로토콜의 스테이트리스성을 유지하면서 해당 문제를 해결하기 위한 아이디어가 도입되어 있습니다. 바로, 멱등성과 안전이라는 성질입니다.

     

    멱등성이란 ‘어떤 조작을 몇 번을 실행해도 결과가 동일한 것’을 의미합니다. 안전이란 ‘조작 대상의 리소스의 상태를 변화시키지 않는 것’을 의미합니다.

     

    메서드 성질
    GET, HEAD 멱등이고, 안전하다.
    PUT, DELETE 멱등이지만, 안전하지 않다.
    POST 멱등이지도, 안전하지도 않다.

    POST는 안전하지도 멱등하지도 않으므로 요청의 결과로 무엇이 일어날지 모릅니다. 따라서 클라이언트는 POST를 여러 번 보내는 것에 신중하지 않으면 안됩니다.

    위의 표에 적혀있는 것처럼 GET과 HEAD가 멱등이고 안전하며, PUT과 DELETE가 멱등이라는 것은 HTTP 스펙으로 정해져 있습니다. 웹 서비스와 웹 API의 설계를 잘못하여 메서드가 안전하지 않거나 멱등이 아니게 되지 않도록 주의해야 합니다.

    HTTP에서는 아주 적은 수의 메서드만 정의하고 있습니다. 이렇게 REST의 통일 인터페이스의 제약 덕분에 프로토콜이 심플하게 유지되었고, 웹이 성공하게 되었습니다.

    GET에 숨겨진 안전성, PUT과 DELETE의 멱등성, 무엇이든 가능한 POST를 가진 HTTP는 각각의 메서드에 맞는 성질과 확장성을 갖춘 뛰어난 프로토콜입니다.

     

     

    HTTP 상태코드

    REST API는 URI를 설계와 더불어 리소스에 대한 응답도 적절하게 반환해야 합니다.

     

    2XX Success

    • 200 OK : 클라이언트의 요청을 정상적으로 수행한 경우
    • 201 Created : 클라이언트가 어떠한 리소스 생성을 요청, 해당 리소스가 성공적으로 생성된 경우 (POST)
    • 204 No Content : 리소스는 성공적으로 생성되었지만, 반환할 내용이 없는 경우

     

    3XX Redirection

    • 리다이렉트 : 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동

     

    4XX Client Errors

    • 400 Bad Request : 클라이언트의 요청이 부적절할 경우
    • 401 Unauthorized  : 클라이언트가 인증되지 않은 상태에서 보호된 리소스를 요청한 경우
    • 403 Forbidden : 접근 권한이 불충분한 경우 등에 의해 서버가 요청을 이해했지만 승인을 거부하는 경우
    • 404 Not Found : 클라이언트가 요청한 자원이 존재하지 않는 경우

     

    5XX Server Errors

    서버 에러는 절대 사용자에게 나타내서는 안된다.

    • 500 : 서버에 문제가 있을 경우

     


    REF

    https://ian-info.tistory.com/14

    https://sangminlog.tistory.com/entry/about-restAPI

    728x90
Designed by Tistory.