본문 바로가기
( ´・・)/개발

[REST API] 기계들의 대화 CRUD (POST, GET, DELETE, PUT, PATCH)

by shinsangah 2023. 3. 11.

ref. https://youtu.be/PmY3dWcCxXI

 

기계와 기계가 웹을 이용해서 통신을 할 때, 정해진 규칙이 있다면 얼마나 좋을까요?

그렇다면, 통신 규칙을 어떻게 정할 것인가에 대해서 덜 고민할 수 있을테니까요.

 

 

 

 

기계와 기계가 규격화된 방식으로 인터넷으로 또 웹을 이용해서 통신할 수 있도록 돕는

통신 규칙인 REST API 에 대해 알려드리겠습니다. REST APIWEB의 통신 규약인 http를 이용합니다.

 

 

API는 컴퓨터의 기능을 실행시키는 방법을 의미합니다.

화면에 "Hello, World" 를 출력하는 방법은 언어마다 다릅니다.

 

파이썬이라면 print('hello world') 라고 할 것이고,

자바스크립트라면 document.write('hello world') 이렇게 할 것입니다.

 

 

print, document.write 와 같은 것 하나하나가 API 라고 할 수 있습니다.

REST API도 컴퓨터의 기능을 실행시키는 명령이라고 할 수 있습니다. 그런데,

 

 

 

REST API는 내 컴퓨터가 아니라 남의 컴퓨터를 실행시킵니다.

예를 들어,나의 APP이 이 주소로 접속하면, 구글캘린더에 등록되어있는 나의 캘린더를 구글캘린더에서 이렇게 출력해줍니다.

또, 아래 주소로 접속하면 트위터의 글을 가져올 수 있기도 합니다.

 

가져오는 것 뿐만이 아니라, 내용을 추가하고 수정하고 삭제하는 것도 물론 가능합니다.

이렇게 인터넷과 웹을 통해서 나의 컴퓨터를 제어할 때 어떻게 하면 시행착오를 줄이고,

더 좋은 API를 만들 수 있는가에 대한 고민의 결과물이 REST API 라고 할 수 있습니다.

 

REST API는 특정 기술을 의미하는 것이 아니에요. http를 이용해서 기계들이 통신할 때,

http가 가진 잠재력을 최대한 이용할 수 있도록 유도하기 위한 말하자면, 모범 사례라고 할 수 있습니다.

 

여러분이 블로그나 SNS와 같은 서비스를 운영한다고 한 번 쳐보세요.

하나 하나의 글을 topic 이라고 부르기로 했다면, 이런 모습으로 데이터를 가지고 있겠지요.

이런 데이터들을 REST API 에서는 Resource 라고 합니다.

 

 

 

Resource를 REST API로 표현해봅시다. Resource는 URI를 통해서 표현 됩니다.

이때 topic 전체를 식별하고 싶다면, 또는 여러개의 토픽을 식별하고 싶다면, 이런 URI를 사용하면 됩니다. http://example.com/topics 이러한 것을 Collection 이라고 해요.

 

Collection은 저기 topics 라는 이름을 보시면 알겠지만, 복수형을 사용합니다.

그리고 이렇게 한 건 한 건의 데이터를 Element 라고 합니다.

 

즉, Collection은 Element가 모여있는 것Collection,

Collection에 하나 하나의 데이터Element라고 합니다.

 

id 값을 Element에서 사용하는 것이 일반적입니다. 저기 있는 1번 처럼요.

하지만, 이름으로 만약에 식별할 수 있다면 이렇게 단수형으로 사용합니다. http://example.com/topics/rest

 

자, 그런데 Resource를 URI로 표현하는 것만으로는 아무것도 할 수 없습니다.

URI는 단지 그 정보를 식별하는 이름일 뿐이고, 이 정보를 가공할 수 있어야 합니다.

 

 

 

📶 URI란? (feat. URL, URL, URN)

URI (Uniform Resource Identifier) 인터넷 자원을 나타내는 고유 식별자 입니다. URI 에 I 가 Identifier 입니다. 인터넷에 있는 자료의 id 이다. 라고 생각하면 좋을 것 같습니다. 다른 자료가 똑같은 이름을

kddk.tistory.com

 

 

 

 

 

정보에 대한 가공방법은 굉장히 많아 보이지만, 사실 4가지 밖에 없습니다.

Create Read Update Delete즉, 생성 / 읽기 / 수정 / 삭제 입니다.

이런 작업들을 REST API 에서는 method (메소드) 라고 부릅니다.

REST API는 WEB의 통신 규약인 http를 이용하기 때문에, http가 가지고 있는 메소드를 이용하거든요.

 

 

 

 

 

http에서 create를 위해서 준비된 메소드는 post 입니다.

실제 웹 애플리케이션은 form을 이용해서 데이터를 전송할 때 수정, 생성, 삭제할 때 모두 post 를 쓰지만,

사실은 post는 본래 '생성'을 위해서 준비된 기능이였습니다.

 

REST API는 http들의 메소드들을 본래 용도에 맞게 쓰자는 것도 중요한 목표이기 때문에

post'생성'을 위해서 쓰기로 했습니다. '읽기' get 입니다.'삭제'delete 라는 메소드를 쓰는 것입니다.

'수정'이 조금 까따로운데요.'수정'은 전체 내용을 교체하는 put이 있고, 부분을 변경하는 patch가 있습니다.

 

 

 

지금부터는 웹브라우저에서 웹서버에 Ajax를 위한 API인 patch 라는 것을 이용해서

REST API를 이용하는 방법을 소개해보겠습니다. 웹에 국한된 내용이 아닙니다.

 

( * Ajax란? https://developer.mozilla.org/ko/docs/Web/Guide/AJAX/Getting_Started)

 

웹브라우저 대신에 여러분이 만든 모바일 앱이나, 자신의 웹서버가 다른 웹서버와

REST API를 이용해서 다른 서버와 통신할 수도 있습니다.

 

 

왼쪽은 REST API를 제공하는 서버의 데이터 상태를 보고 계시구요.

오른쪽에는 그 서버에 접속해서 이런 저런 일들을 하려고 하는 클라이언트 라고 생각해주세요.

우리 서버에는 2개의 Resource가 있습니다. ("topics", "comments")

 

즉, topics에 속해있는 댓글(comments) 2개가 들어가 있는 상태 입니다.

바로 저 data 라는 말은, 저 state를 어떻게 하면 REST API로

표현하고 생성하고, 수정하고 삭제할 것인가를 REST API 실험실에서 해보겠습니다.

 

 

왼쪽에 REST API를 제공하는 서버에 자바스크립트를 이용해서 생성, 읽기, 수정, 삭제, 관계를

표현하는 방법을 자바스크립트 코드로 구현을 했는데요. 여기 있는 자바스크립트 코드가 중요한 것은 아닙니다.

중요한 것은 어떻게 브라우저와 서버가 통신하는가 라는 것을 보는 것이 중요합니다.

 


 

생성 - POST

 

 

실험을 위해서 검사를 하면, 여기서 웹 브라우저와 서버가 통신하는걸 보기 위해서

Network 탭을 엽니다. 그리고 ESC 버튼을 눌러서 서버 쪽에서 만들어진 데이터를 console 창에 표시하게 한다.

일단, Resource를 생성부터 해봅시다. "topics" 라는 resource에 문서 하나 더 추가위해 그걸 위한 코드가 오른쪽 입니다.

 

 

여기에서 title은 fetch, body는 fetch is 블라블라 하는 데이터를 resource로 추가하려고 하는데,

저 객체 데이터를 JSON의 형태로 바꿀 것이다. 그러니까 서버한테 내가 만든 데이터는 JSON이야.

라고 알려주기 위해서 이렇게 'application/json' 'content-type' 이 json 이라고 알려주는 것이다. 

 

 

이 때 중요한 것은 우리가 추가하려는 저 데이터를 왼쪽에 있는 "topics" 라고 하는 resource에 추가하려고 하는 것이다.

그러니까 데이터의 주소는 'topics' 이고, resource의 식별자이고요.

 

그리고 우리가 하려고 하는 일은 데이터를 생성하려고 하는건데,

생성이 http 프로토콜에서는 POST 이기 때문에 메소드로 POST를 쓴다.

라고 하는 것이 바로 REST API의 권고안인 것입니다.

 

그리고 이제 json 데이터를 쓰겠다! 이런 것은 여러분들의 선택입니다.

REST API가 규정하는 것이 아니고, 여러분이 원하면 JSON을 쓸 수도 있고, XML을 쓸 수도 있습니다.

 

중요한 것은 데이터인 Resource는 URI fetch('topics', 를 통해 식별합니다.

그리고 어떤 행위를 할 때는 메소드의 이름 ('POST') 을 적당히 http의 규정대로 사용하는 것이 핵심입니다.

 

 

그럼 제가 이 코드를 한 번 실행시키면 왼쪽 "topics" : [ { 에 데이터가 추가되는 것과 콘솔에 출력되는 내용을 한 번 보시죠.

데이터가 잘 추가 되었습니다. 다시 말해서 resource가 POST 된 것 입니다.

그리고 status가 201이라고 뜨고, 보시는 것처럼 결과가 나옵니다. 우리가 방금 추가한 데이터가 출력된 것이죠.

 

 

이것을 좀 더 자세하게 보기 위해서 topics 라고 하는 클라이언트와 서버가 통신한 내용을 자세히 들여다보면서

어떤 식으로 http Request Response가 이루어지는가 살펴보도록 해요. REST API를 이용했을  말이죠.

Requset(요청)의 실제 내용을 보려면 view source를 보시면 원래 브라우저와 서버가 통신한 실제 데이터를 볼 수 있어요.

 

 

여기 보시면, 첫번째로 브라우저는 서버한테 POST 라고 적어서 보냅니다. 저것이 바로 메소드이고,

POST는 '생성한다' 라는 뜻입니다. 그 다음 두번째로 나오는 것은 URI ( /topics )입니다.

 

 

즉, 우리가 생성하고자 하는 데이터는 /topics 가 가리키는 데이터니까 파란색 음영표시한 저 데이터 입니다.

 

 

그리고 실제 내용은 저기 view source를 보면 음영표시한 이렇게 생긴 데이터를 전송 했는데,

 

 

이 데이터가 어떤 데이터 타입인지 우리가 알려줬냐면, 위에 content-type : application/json 이니까

서버는 쟤를 json의 형태에 맞게 파싱(Pharsing) 해서 여러가지 처리를 알아서 해주겠지요.

 


파싱 (Pharsing)

웹페이지에서 원하는 데이터를 추출하여 가공하기 쉬운 상태로 바꾸는 것 입니다.

 

 

 

웹페이지에서 떠다니는 데이터 (실제로는 떠다니지 않지만) 는 리스트, 딕셔너리 같은 자료구조와 달라

사용자 마음대로 접근하고, 자르고, 추가하고, 지지고 볶기가 쉽지 않습니다.

그렇기 때문에 이런 데이터들을 다루기 쉬운 형태로 바꿔주는 과정이 필요한데,

이 역할을 하는 함수나 프로그램을 파서(Parser) 라고 하며, 이 과정을 파싱(Pharsing) 이라고 합니다.

 

웹 크롤링을 할 때 필연적으로 만나게 되며, python에서는 beautifulSoup 이라는

라이브러리를 사용하여 html 문서를 파싱한다.

 


 

그럼 서버는 이 클라이언트에게 Response (응답) 을 할건데요. 그 응답의 구체적인 메시지를 보면 이렇게 생겼습니다.

일단은 201이라고 하는 응답코드를 보내주었어요. 201은 데이터의 생성이 성공적으로 끝났다는 것을 서버가

클라이언트에게 알려줄 때 사용하는 약속된 번호입니다. 그리고 그 번호의 이름이 created 인 것입니다.

 

 

즉, REST API 에서는

서버 쪽에서 어떠한 일을 처리하고, 그 처리한 일의 결과를 응답 코드와 응답 메시지를 통해서 응답하자

라는 것이 REST API의 핵심이라고 할 수 있습니다.

그리고 그렇게 해서 서버한테 클라이언트한테 응답한 데이터는 여기 있는 이런 식의 데이터인 것입니다.

 

 

이 데이터가 어떤 데이터 타입인지를 서버가 클라이언트에게 알려주기 위해서

Response 즉, 응답 Header에 Content-type이 application/json 이라는 것을

서버가 이번에는 클라이언트에게 알려주고 있는 것이다.

 

 

REST API에서 규정하고 있는 것과 규정하고 있지 않은 것을 알려드릴게요.

REST API에서 규정하고 있지 않은 것은 클라이언트와 서버가 어떤 데이터 타입으로 통신할 것인지를 규정하지 않아요.

JSON 쓰셔도 되고, XML을 쓰셔도 됩니다. 그러면 규정하고 있는 것은 Resource를 식별할 때는 URI를 통해 /topics를 식별하고,

 

 

그리고 어떤 행위를 할 때는 POST, GET, PATCH, DELETE와 같은 http의 고유한 메소드를 이용합니다.

 

 

그리고 결과를 알려줄 때는 응답 코드를 사용하는 것을 통해서 결과를 알려주는 것이다. (201)

라는 것을 권고하고 있는 것이 REST API 라고 얘기할 수 있습니다.

즉, http 프로토콜을 http 프로토콜답게 사용하자는 것이 REST API가 주장하고자 하는 바 인 것입니다.

 


Collection 읽기 - GET

 

이번에는 GET(읽기)를 한 번 해볼게요. 왼쪽에 resource를 읽는데 두 가지 타입이 있습니다.

첫 번째는 여러개를 그룹핑해서 가져오는 즉, collection에 읽는 방법이 있구요.

두 번째는 하나의 데이터 element를 읽는 방법이 있습니다.

 

 

Collection에 읽을 때는 topics 라고 하면, 그것은 저 topics에 해당되는 저 resource 데이터 전체를 가져오는 것,

실행을 시키면 topics 라고 (파란색 음영) 한 줄이 추가가 되었구요.

 

 

보시는 것처럼 Request (요청) 를 할 때는 GET 으로 /topics 을 topics resource에 있는 데이터를

GET 가져오는 것이죠. 그것에 대한 Response (응답) 코드로는 200, 즉! 잘 끝났다. 라는 것을 우리한테 응답해주고요.

 

 

그 데이터는 이렇게 생겼고,

 

 

이 데이터는 Content-type: application/json; 이니까 JSON의 데이터 타입에 맞게 해석해서 사용하면 되는 것 입니다.

 

 

그러면 이번엔 collection이 아니라, 한 건 한 건에 구체적인 데이터를 가져올 때는 어떻게 하는가!

여기 보시면, topics/2 2번, 즉 이 데이터의 식별자를 뒤에다 적어주는 것을 통해서 요청을 합니다.

 

 

실행을 시키면 이렇게 2 한줄이 추가되고, Headers를 살펴보면 Request (요청) 부분에서

보시는 것처럼 GET 방식으로 topics/2 를 가져왔다는 것입니다. 이것이 바로 읽기에 대한 것입니다.

 

읽기는 이렇게 2가지 방식이 있습니다.

하나는 Collection, 하나는 Element를 읽어오는 방식이 좀 다르다는 점을 기억하시면 됩니다.

 


부분수정 - PATCH

 

 

이번에는 Resource를 수정하는 방법을 살펴보겠는데요. 수정 방법은 크게 두 가지가 있습니다.

부분 수정이 있고, 전체 수정이 있습니다. 부분 수정은 PATCH, 전체 수정은 PUSH 입니다.

 

 

우리가 topics resource에 2번 데이터 방금 추가된 저것이죠.

우리가 데이터를 전송할 때 title 데이터만 이렇게 딱 보내고, 여기 body 데이터는 보내지 않았어요.

그러면, 왼쪽 데이터가 어떻게 바뀔 것인가 한 번 보도록 하죠.

 

 

보시는 것처럼 이렇게 "fetch - patch" 되거든요. 즉, 여러분이 이 title만 언급하면,

title이 title만 수정되고, 나머지에는 영향이 가지 않습니다. 이것이 바로 부분수정 PATCH 입니다.

 

 

그 때 프로토콜은 Request (요청) 는 PATCH 라는 것을 사용하는 것을 알 수 있습니다.

 


전체수정 - PUT

 

 

그러면 이제 PUT은 어떻게 되나 한 번 봅시다. 실행을 하면,

우리가 title만 데이터를 보냈더니 title만 살아있고, body는 사라졌습니다.

 

즉, PUT은 전체를 교체하는 것입니다. 우리가 전송한 이 데이터로 전체를 교체하는거기 때문에

식별자인 id를 제외하고, 여러분이 언급하지 않은 데이터는 삭제된다는 것 이것이 바로 PUT 입니다.

 

 

이번에는 데이터를 DELETE (삭제) 를 시켜보겠습니다.

DELETE를 시킬 때는 Resource를 'topics/2' 이렇게 지정하고, 메소드를 'DELETE'를 하시면 되는데요.

실행하면, 단순하게 싹 삭제가 됩니다. 자세하게 설명하지 않아도 될 정도로 단순하죠.

 

 

삭제를 할 때, 어떤 Element만 삭제 할 때가 있고, Collection을 삭제할 수도 있겠죠.

Collection을 삭제를 하게 되면 그 데이터 전체가 삭제가 되는데 상당히 위험한 명령이기 때문에 막혀있는 경우가 많습니다.

 


관계

 

또 하나 우리가 REST API 사용할 때 아리송할 수 있는 부분이 뭐냐면,

어떠한 Resource와 Resource가 관계를 맺고 있을 때 걔를 어떻게 URI로 표현할 것인가 그것이 애매할 수 있거든요.

 

 

이를 테면, 여기 있는 topics는 comment(댓글)을 포함하고 있습니다.

그리고 topicId를 통해서 "topicId": 1 여기에 있는 1번은 topics에 있는 "id": 1, 1번을 의미하니까

여기에 있는 2개의 댓글은 topics에 있는 "REST" 라고 하는 글 하나에 종속되어 있다는 관계를 맺고 있어요.

 

 

이것을 어떻게 URI로 표현을 하는가, 그 때는 보시는 것처럼 이렇게 부모가 되는 것을 앞에 적고

'topics/1/comments' 그 부모의 Element에 id 값을 줬고, 그 다음에 자식이 되는 종속되어있는

Resource의 이름을 uri로 적어서 표현한다 라는 것이 약속이 되어 있는 것입니다.

 

 

 

 

이렇게 해서 REST API에 대해서 알아봤는데요. REST API는 그렇게 복잡한 권고안이 아닙니다.

기계와 기계가 http를 이용해서 통신할 때, Resource는 URI, 행위는 METHOD 로

결과는 Response 응답 코드로, http가 원래 가지고 있는 의미를 잘 활용하지 않은 것이라고 할 수 있습니다.