Page

관련 포스팅

2023년 9월 19일 화요일

RESTful API 및 postman 학습

이번 포스팅에서는 RESTful API와 postman에 대해서 학습을 하면서 정리를 해보려 한다.


RESTful API란?

RESTful API는 REST(REpresentational State Transfer) 원칙을 따르는 웹 서비스를 의미한다. REST는 네트워크 아키텍처 원칙의 집합이며, 이 원칙을 따르면 확장성 있는 시스템을 만들 수 있다. RESTful API는 일반적으로 HTTP 프로토콜을 사용하며, 웹 서비스의 리소스에 접근하기 위한 경로(URL)와 메서드(HTTP 메서드)를 정의한다.

예를 들어, 게시판의 글을 관리하는 RESTful API가 있다고 가정하자.

  • 글 목록을 가져오려면: GET /posts
  • 특정 글을 가져오려면: GET /posts/{id}
  • 글을 작성하려면: POST /posts
  • 글을 수정하려면: PUT /posts/{id}
  • 글을 삭제하려면: DELETE /posts/{id}

이런 식으로 리소스(URL)와 행동(HTTP 메서드)를 조합해 서비스를 사용한다.

REST 원칙이란?

REST(REpresentational State Transfer)는 분산 하이퍼미디어 시스템을 위한 아키텍처 스타일이다. 여기서 분산 하이퍼미디어 시스템은 네트워크에 분산된 여러 서버와 클라이언트가 상호 작용하는 하이퍼미디어 시스템을 의미한다. 하이퍼미디어는 텍스트, 이미지, 비디오, 오디오 등 다양한 형태의 미디어가 하이퍼링크로 연결되어 있는 구조를 말한다.

분산 시스템에서는 여러 노드가 서로 독립적으로 동작하면서 필요에 따라 정보나 자원을 공유한다. 예를 들면, 웹은 대표적인 분산 하이퍼미디어 시스템이며, 여러 웹 서버가 인터넷을 통해 연결되어 있다. 이런 웹 서버들은 각자 다양한 미디어 리소스(HTML, 이미지, 비디오 등)를 저장하고 있으며, 웹 브라우저(클라이언트)는 이러한 리소스를 HTTP 프로토콜을 통해 요청하고 받아볼 수 있다.

하이퍼링크를 통해 다양한 미디어가 서로 연결되어 있기 때문에 사용자는 웹 브라우저에서 링크를 클릭하거나 다른 인터랙션을 통해 원하는 정보나 서비스에 쉽게 접근할 수 있다. 이렇게 분산된 시스템에서의 리소스 접근과 상호 작용이 원활하게 이루어지기 위해 REST와 같은 아키텍처 스타일이 필요하다. 즉, REST 원칙은 웹 서비스를 개발할 때 많이 사용되며, 다음과 같은 특징을 가진다.

  1. Stateless: 각 요청은 모든 정보를 포함해야 하며, 서버는 클라이언트의 상태를 저장해서는 안 된다.

  2. Client-Server: 클라이언트와 서버는 독립적으로 동작해야 하며, 하나가 변경되어도 다른 하나에는 영향을 주지 않아야 한다.

  3. Cacheable: 응답은 캐시 가능하거나 캐시 불가능하다고 명시해야 한다. 이를 통해 성능을 향상시킬 수 있다.

  4. Uniform Interface: 일관된 인터페이스를 가져야 한다. 이 원칙은 아래의 하위 원칙을 포함한다.

    • Resource-Based: 리소스(데이터 개체)는 URL로 식별된다.
    • Manipulation of Resources Through Representations: 리소스는 HTTP 메서드를 통해 조작된다.
    • Self-descriptive Messages: 각 메시지는 처리 방법을 명확히 해야 한다.
    • Stateless Interactions Through Hypermedia: 하이퍼미디어를 통해 상태 전이가 이루어져야 한다.
  5. Layered System: 클라이언트는 최종 서버에 직접 연결되어 있는지, 중간 레이어를 통해 연결되어 있는지 알 필요가 없다. 이를 통해 확장성을 높일 수 있다.

  6. Code on Demand (Optional): 필요에 따라서는 코드(예: 자바스크립트)를 클라이언트에 전송할 수 있다. 이 원칙은 선택적이다.

이 원칙들을 따르면 RESTful하다고 할 수 있다. 이 원칙들을 준수하면 유지보수가 쉬우며, 확장성 높은 웹 서비스를 만들 수 있다.


postman이란?

Postman은 API 테스팅 툴로, API를 개발하거나 테스트할 때 사용된다. HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용해 서버에 요청을 보내고 응답을 받을 수 있다. 그래서 서버의 기능을 쉽게 테스트하고 디버깅할 수 있다.

HTTP 메서드는 클라이언트가 웹 서버에게 어떤 종류의 작업을 수행하길 원하는지를 나타내는 방법 중 하나다. 이런 메서드를 이용하면 같은 URL에 대해서도 다양한 연산을 수행할 수 있다. 주로 사용되는 HTTP 메서드는 GET, POST, PUT, DELETE 등이 있다.

HTTP 메서드 (GET, POST, PUT, DELETE)

GET

GET 메서드는 서버에게 지정한 리소스의 정보를 요청한다. GET은 오직 데이터를 조회하는 데 사용되므로, 서버의 상태나 데이터를 변경하면 안 된다. 예를 들어, 브라우저 주소창에 URL을 입력하면 GET 요청이 서버로 전송되고, 서버는 해당 페이지의 HTML 파일을 반환한다.

GET은 HTTP 프로토콜을 사용하는 클라이언트가 서버의 특정 리소스를 요청할 때 사용하는 메서드다. 이건 서버에서 클라이언트로 정보를 "보내는" 것과는 좀 다르다. 실제로는 클라이언트가 서버에 "이 정보를 주세요"라고 요청을 보내는 것이고, 그 요청을 받은 서버가 해당 정보를 클라이언트에게 전달한다.

GET 요청은 URL을 통해 이루어지며, 요청에 필요한 데이터는 URL의 일부로 전달된다. 예를 들어, "https://www.example.com/products?id=1" 같은 형태로 표현될 수 있다. 여기서 클라이언트는 "id가 1인 상품 정보를 주세요"라고 서버에 요청한다.

GET은 안전하고(idempotent하다고도 함), 캐시 가능하며, 브라우저 히스토리에 남는다. 또한 주로 무언가를 생성하거나 변경하지 않고, 단순히 읽기 위한 용도로 사용된다.

GET 요청은 정보를 검색하는 데 사용되기 때문에, 서버의 상태나 데이터를 변경하지 않아야 한다. 이러한 이유로 GET은 데이터를 조회할 때 주로 사용되며, 다른 작업을 위해서는 POST, PUT, DELETE 등의 다른 HTTP 메서드를 사용한다.

GET 요청은 원칙적으로 서버의 상태나 데이터를 변경하면 안 된다. GET은 "idempotent"하고 "safe"하다고 설계되었기 때문이다.

"idempotent"이라는 말은 동일한 요청을 여러 번 해도 서버 상태가 바뀌지 않아야 함을 의미한다. "safe"는 해당 요청이 서버의 상태를 변경하지 않는다는 것을 의미한다.

예를 들어, 웹 브라우저의 주소창에 URL을 입력하고 엔터를 누르면, 브라우저는 해당 URL의 리소스를 서버로부터 GET 요청으로 가져온다. 이 과정에서 서버의 상태가 변경되어서는 안 된다.

하지만 실제로는 개발자의 실수나 특정 상황에 의해 GET 요청이 서버의 상태를 변경하는 경우도 있다. 이런 행위는 RESTful API의 원칙에 어긋나며, 이로 인해 예상치 못한 부작용이 발생할 수 있다. 따라서 GET 요청을 설계할 때는 이러한 원칙을 지키는 것이 중요하다.

GET 메서드는 주로 서버로부터 정보를 조회할 때 사용한다. 이 요청은 서버의 상태나 데이터를 변경하지 않아야 하며, idempotent하다. 즉, 같은 GET 요청을 여러 번 해도 서버의 상태가 변하지 않아야 한다.

예를 들어, 웹 브라우저에서 특정 웹페이지를 열거나, API로부터 데이터를 가져올 때 GET 메서드를 사용한다.

  1. 웹 페이지 요청 예시: 사용자가 웹 브라우저 주소창에 "http://www.example.com"를 입력하고 Enter를 누르면, 브라우저는 GET http://www.example.com 요청을 서버에 보낸다. 서버는 요청을 처리한 후 해당 웹 페이지의 HTML을 반환한다.

  2. API 데이터 요청 예시: 특정 사용자의 정보를 가져오려면 다음과 같은 형태의 GET 요청을 사용할 수 있다.

    GET /users/123
    

    이 요청을 받은 서버는 ID가 123인 사용자의 정보를 JSON 형태로 반환할 것이다.

    {
        "id": 123,
        "name": "John Doe",
        "email": "john@example.com"
    }
    
  3. Query Parameter를 포함한 GET 요청 예시: 검색 쿼리나 페이지네이션 정보를 전달할 때 GET 요청에 쿼리 파라미터를 포함할 수 있다.

    GET /users?search=John&page=2
    

    이 요청은 이름에 "John"이 포함된 사용자를 찾고, 그 중 두 번째 페이지의 정보를 가져오라는 의미다.

이런 식으로 GET 메서드는 데이터를 조회하는 데 주로 사용된다.

POST

POST 메서드는 서버에게 새로운 리소스를 생성하도록 요청한다. 데이터는 HTTP 메시지의 바디에 담겨 전송된다. POST는 주로 웹 폼을 통한 사용자 입력값을 서버로 전송하거나, 파일을 업로드할 때 사용된다.

POST 역시 클라이언트가 서버에 요청하는 HTTP 메서드다. 하지만 GET과는 달리, POST는 서버의 상태나 데이터를 변경할 수 있다. POST 요청은 보통 서버에 새로운 데이터를 추가하거나 리소스를 생성할 때 사용된다.

예를 들어, 웹 폼을 통해 사용자가 정보를 입력하고 "제출" 버튼을 누르면, 그 데이터는 서버에 POST 요청으로 전달되고 서버는 그에 따라 새로운 데이터를 생성하거나 기존 데이터를 수정한다.

POST 요청은 HTTP 메시지 본문에 데이터를 담아 전송한다. 이러한 특성 때문에 GET보다 더 많은 양의 데이터를 전송할 수 있다. 그리고 POST 요청은 idempotent하지 않다. 즉, 동일한 POST 요청을 여러 번 전송하면 서버 상태가 여러 번 변경될 수 있다. 예를 들어, 같은 '상품 추가' 요청을 두 번 보내면, 두 개의 상품이 추가될 것이다.

또한 POST는 안전하지 않은 연산을 수행하기 때문에, 캐싱이나 브라우저 히스토리에 남기는 것이 적절하지 않을 수 있다. 이러한 이유로, 데이터를 생성하거나 수정할 때 주로 사용된다.

POST 메서드는 주로 서버에 새로운 데이터를 생성하거나 전송할 때 사용한다. 이러한 요청은 서버의 상태나 데이터를 변경할 수 있으므로 idempotent하지 않다.

  1. 회원 가입 예시: 사용자가 웹 사이트에서 회원 가입을 할 때, 일반적으로 다음과 같은 형태의 POST 요청이 사용된다.

    POST /users
    

    보낼 데이터(Payload):

    {
        "username": "john_doe",
        "password": "securePassword",
        "email": "john@example.com"
    }
    

    이런 요청을 받은 서버는 새로운 사용자를 생성하고, 성공 여부나 생성된 사용자의 정보를 반환할 것이다.

  2. 댓글 작성 예시: 블로그 포스트에 댓글을 작성하는 경우도 POST 메서드를 사용할 수 있다.

    POST /posts/1/comments
    

    보낼 데이터(Payload):

    {
        "comment": "Great post!",
        "author": "john_doe"
    }
    

    서버는 이 요청을 받아 댓글을 해당 포스트에 추가하고, 성공 여부를 반환한다.

  3. 파일 업로드 예시: 사용자가 웹 사이트에 이미지나 문서 파일을 업로드 하는 경우에도 POST 메서드를 사용한다.

    POST /files/upload
    

    이 요청에는 파일 데이터가 포함되어 있을 것이며, 서버는 이를 받아 저장한 후 결과를 반환한다.

  4. 로그인 예시: 사용자가 로그인을 하는 경우에도 POST 메서드를 사용할 수 있다. 이는 보안을 위해 사용자의 ID와 비밀번호를 URL에 노출시키지 않기 위해서다.

    POST /login
    

    보낼 데이터(Payload):

    {
        "username": "john_doe",
        "password": "securePassword"
    }
    

    서버는 이 정보를 확인하고, 토큰이나 세션 정보를 반환할 것이다.

이렇게 POST 메서드는 서버에 데이터를 생성하거나 변경하는 다양한 용도로 사용된다.

PUT

PUT 메서드는 서버의 특정 리소스를 업데이트하거나, 존재하지 않을 경우 새로 생성하는 것을 요청한다. POST와 비슷하게 데이터를 메시지 바디에 담아 전송한다. 그러나 PUT은 idempotent하다. 즉, 같은 요청을 여러 번 수행해도 결과가 동일하게 유지된다.

PUT 메서드는 HTTP에서 사용하는 요청 방식 중 하나다. PUT은 클라이언트가 서버에게 특정 리소스를 업데이트하거나 생성하도록 지시할 때 사용한다.

  1. 리소스 업데이트: 클라이언트는 서버에게 정확한 리소스 URI와 함께 새로운 데이터를 보낸다. 서버는 해당 URI의 리소스를 클라이언트의 데이터로 업데이트한다.

    • 예: PUT /users/123 → 사용자 123의 정보를 새로운 데이터로 업데이트
  2. 리소스 생성: 만약 지정한 URI에 리소스가 없으면, 서버는 새로운 리소스를 해당 URI에 생성할 수 있다.

    • 예: PUT /users/124 → 사용자 124가 없다면 새로운 사용자 124를 생성

PUT은 idempotent하다. 즉, 동일한 PUT 요청을 여러 번 수행해도 서버에서의 최종 결과는 같아야 한다. 예를 들어, 동일한 데이터로 동일한 URI에 PUT 요청을 두 번 보내면, 두 번째 요청은 첫 번째 요청에 아무런 영향을 주지 않는다.

주의할 점은 PUT 요청은 대체적으로 전체 리소스를 대체한다. 즉, 업데이트를 할 때 일부분만 업데이트하지 않고 전체 데이터를 새로 작성한다. 일부만 변경하고 싶을 경우 PATCH 메서드를 사용한다.

예시:

PUT /users/123 HTTP/1.1
Host: example.com
Content-Type: application/json

{
    "name": "John",
    "email": "john@example.com"
}

이 예시에서는 사용자 123의 name과 email을 새로운 값으로 업데이트하거나, 사용자 123이 없다면 새로 생성한다.

DELETE

DELETE 메서드는 서버에게 지정한 리소스를 삭제하도록 요청한다. DELETE도 idempotent한 특성을 가진다. 한 번 리소스를 삭제한 후, 같은 리소스에 대해 다시 DELETE 요청을 보내도 결과가 바뀌지 않는다.

DELETE 메서드는 서버의 특정 리소스를 삭제할 때 사용한다. DELETE 요청이 성공적으로 처리되면, 서버는 보통 200 OK 또는 204 No Content와 같은 상태 코드를 반환한다. DELETE는 idempotent하다, 즉 동일한 DELETE 요청을 여러 번 수행하더라도 동일한 결과가 나온다.

DELETE 메서드 사용 예시

  1. 게시물 삭제

    DELETE /posts/1
    

    이 요청은 ID가 1인 게시물을 삭제하라는 의미다. 요청이 성공하면 서버는 해당 게시물을 데이터베이스에서 삭제하고 성공 메시지를 반환한다.

  2. 사용자 계정 삭제

    DELETE /users/john_doe
    

    이 요청은 "john_doe" 사용자 계정을 삭제한다. 이렇게 요청을 하면 서버는 해당 사용자 계정을 삭제하고 결과를 반환한다.

  3. 카트에서 아이템 삭제

    DELETE /cart/items/5
    

    여기서는 쇼핑 카트에서 ID가 5인 아이템을 삭제하라는 요청이다. 서버는 해당 아이템을 카트에서 삭제하고 결과를 반환한다.

  4. 이미지 파일 삭제

    DELETE /files/image.png
    

    이 요청은 "image.png" 파일을 서버에서 삭제하라는 것을 의미한다. 파일이 성공적으로 삭제되면, 서버는 그에 따른 상태 코드와 메시지를 반환한다.

  5. 팀에서 멤버 삭제

    DELETE /teams/1/members/2
    

    이 경우는 ID가 1인 팀에서 ID가 2인 멤버를 삭제하는 요청이다. 서버는 멤버를 팀에서 삭제하고 결과를 반환한다.

DELETE 메서드는 이처럼 서버의 특정 리소스를 삭제할 목적으로 사용되며, 요청이 처리된 후에는 해당 리소스에 대한 접근이 더 이상 불가능해야 한다.

각 HTTP 메서드는 특정한 목적과 규칙에 따라 사용되므로, API나 웹 애플리케이션을 설계할 때 이를 고려해야 한다. 예를 들어, GET 요청은 사이드 이펙트가 없고 캐싱이 가능해야 하며, POST 요청은 서버 상태를 변경하거나 새 리소스를 생성할 때 사용되어야 한다.

Postman을 사용하면 이런 API를 쉽게 테스트할 수 있다. 원하는 메서드와 파라미터, 헤더 등을 설정하고 요청을 보낼 수 있으며, 서버로부터 받은 응답을 바로 확인할 수 있다. 이런 방식으로 API가 제대로 동작하는지, 예상대로 데이터를 반환하는지 등을 체크할 수 있다.

idempotent하다는 것의 의미

"idempotent하다"는 같은 연산을 여러 번 수행해도 결과가 항상 동일하다는 의미다. 다시 말해, 한 번의 요청과 여러 번의 요청이 서버 상태에 똑같은 영향을 미치는 것을 말한다.

예를 들어, DELETE 메서드를 사용하여 특정 리소스를 삭제했다면, 그 리소스는 서버에서 삭제된 상태가 된다. 이 상태에서 같은 DELETE 요청을 다시 보내도, 이미 삭제된 리소스는 더 이상 존재하지 않기 때문에 서버 상태에 변화가 없을 것이다.

비슷하게 PUT 메서드로 특정 리소스를 변경하면, 동일한 PUT 요청을 여러 번 수행해도 마지막 상태와 동일한 상태를 유지하게 된다. 예를 들어, 어떤 문서를 PUT 메서드로 "Hello World"라는 내용으로 변경했다면, 동일한 PUT 요청을 다시 수행해도 문서의 내용은 "Hello World"로 유지된다.

이와 달리 POST 메서드는 idempotent하지 않다. 같은 POST 요청을 여러 번 보내면, 서버에 여러 개의 리소스가 새로 생성될 수 있다. 예를 들어, 쇼핑카트에 아이템을 추가하는 POST 요청을 두 번 보내면, 쇼핑카트에는 같은 아이템이 두 개 추가되는 것이다.

idempotent한 메서드를 사용할 때는, 네트워크 불안정이나 다른 이유로 요청이 중복되더라도 안전하게 처리될 수 있다는 장점이 있다. 이러한 특성 때문에 RESTful API에서는 각 HTTP 메서드의 idempotent 여부를 명확하게 정의하고 있다.


API 테스트 with postman

API 테스트용 Github

위의 깃헙에서는 굉장히 많은 API들을 제공해 주기 때문에 자유롭게 API를 테스트할 수 있다. 예를 들어서, 나는 The Dog라는 API를 이용해 보기로 했으며, 해당 링크를 눌러서 API를 제공받아서 postman에 넣으면 된다.





여기서 GET YOUR API KEY를 누르고 이메일을 입력하면, 그 이메일로 API key를 알려준다.

이제 postman을 설치해보자. 아래의 공식 웹사이트를 통해서 다운로드 받아서 설치하면 된다.

Postman 공식 웹사이트

설치가 끝났으면, 아래와 같이 이메일로부터 제공받은 key와 value를 넣으면 된다.

The dog API 사이트

위의 사이트 문서를 보면 가이드가 자세히 나와있는데, 나는 dog에 대해서 API를 테스트해볼 것이므로, 문서에 있는대로 주소창에는 https://api.thedogapi.com/v1/images/ 라고 넣을 것이고, Params 탭에서는 아래와 같이 size는 small, limit은 10으로 셋팅하고 GET 메서드로 Send를 눌렀다.

즉, 다음과 같은 URL이 만들어진 것이다.

https://api.thedogapi.com/v1/images/search?size=small&limit=10




그러면 이렇게 내가 보낸 요청에 대한 응답이 날라오게 된다. 이것을 조금 더 보기 좋게 하려면, Body아래의 탭에서 HTTP가 아닌 JSON을 선택해주면 된다.




이 API는 GET 요청이다. 왜냐하면 클라이언트가 원하는 데이터를 쿼리를 통해서 서버에 요청하고 그 응답을 받는 API이기 때문이다. 이것을 응용하면 POST, PUT, DELETE 요청 등 다양한 API를 테스트할 수가 있다.


이상으로 RESTful 및 postman에 대해서 간단하게 살펴봤다. 추후에 실제 project를 개발하면서 POST, PUT, 그리고 DELETE 등을 테스트할 때 다시 추가 업데이트를 해보겠다.

댓글 없음:

댓글 쓰기

관련 포스팅