[API] 식당으로 이해하는 REST 아키텍처

집중맞은 도둑력·2024년 12월 12일

웹 개발

목록 보기
14/14
post-thumbnail

현재 포스트는 이후에 습득한 지식으로 인해 내용이 추가, 수정, 삭제될 수 있음

0. 🔖 목차


  1. 시작하기 전에 API란?
  2. 식당 주인이 되어보자
  3. REST 아키텍처
  4. REST API와 RESTful API

1. 시작하기 전에 API란?


어플리케이션 간 통신과 상호작용을 위한 규칙과 인터페이스를 의미한다.

웹 브라우저와 웹 서버 간에 데이터를 주고받을 때 HTTP라는 규약을 사용하듯 API는 어플리케이션과 어플리케이션이 상호작용을 할 때 필요한 규칙들을 의미한다.

예를 들어 클라이언트와 웹 서버간의 상호작용을 한다고 했을 때, 단순히 클라이언트가 서버에게 "나 이 데이터 줘."라고 말해봤자 아무 의미가 없을 것이다. 서버는 사람이 아니기 때문에 저런 규칙도 없는 자연어에 응답할 기술도, 필요도 없다.

그렇기 때문에 서버측에서 클라이언트에게 제공할 기능들을 URI 형태로 제공하는데 이것을 API라고 볼 수 있다. 두 어플리케이션(클라이언트, 서버) 사이에 상호작용을 위한 인터페이스이기 때문이다.

API는 웹 서버에서만 쓰이는 용어가 아니고 Window API와 같이 운영체제에서 개발자로 하여금 Windows 시스템 리소스와 서비스를 사용할 수 있게 하는 인터페이스도 있다.

쉽게 비유하자면 내가 식당을 차렸는데(어플리케이션을 만들었는데) 손님(다른 어플리케이션 또는 클라이언트)에게 내 식당의 요리를 제공하기 위해(내 어플리케이션의 기능 혹은 자원을 사용할 수 있게 하기 위해) 메뉴판을 만들듯이 API도 이와 같이 생각하면 편하다.

그래서 REST API를 이해하기 위해 API를 식당의 메뉴판으로 비유하는 것으로 시작하겠다.

2. 식당 주인이 되어보자


REST 아키텍처를 좀 더 쉽게 이해하기 위해, 당신이 식당 주인이 되는 상상을 한번 해보자.

당신은 있는 돈, 없는 돈을 다 털어 빚까지 끌어모아 서울 신촌 한복판에 작은 양식 레스토랑을 오픈했다.

이 지역은 외국인들이 많이 방문하는 곳이라 손님의 2/3가 외국인이었다. 국적을 묻지는 않았지만 손님의 말투나 외모로 보아 미국, 일본, 중국, 파키스탄(?) 등 다양한 나라에서 온 사람들 같았다.

당신은 손님에게 최상의 서비스를 제공하고 싶은 마음에 메뉴판을 한국어뿐만 아니라 영어, 일본어, 중국어, 우르두어로도 작성했다. 문제는... 메뉴판이 기괴할 정도로 복잡해졌고 새로운 메뉴를 추가할 때마다 번역 과정을 거쳐야 하니 일이 너무 번거로웠다.

게다가 나름의 ‘배려’를 보여주고자 손님마다 맞춤형 서비스를 제공했다. 파키스탄인으로 보이는 손님에게는 돼지고기를 빼고, 중국인 손님에게는 빨간 소스를 더 뿌려주며, 일본인 손님에게는 조용한 자리를 추천했다. 처음에는 이런 서비스가 뿌듯했지만, 시간이 지나면서 혼란이 커졌다.

3년 후, 식당이 잘 돼서 2호점을 냈다. 그런데 얼마 지나지 않아 2호점 매니저로부터 연락이 왔다. 단골 손님으로 보이는 사람이 "3년째 단골인데 이번엔 왜 서비스가 없냐"고 항의했다는 것이다. 돌이켜보면 1호점에서는 손님의 얼굴을 기억해 서비스를 제공했지만, 2호점 직원들은 그 손님의 얼굴을 알 수 없었다.

한편 주방에서는 메뉴 이름을 두고 불만이 터져 나왔다. 당신이 “봉골레 스파게티”를 메뉴에 추가하며 ‘천사의 머릿결’이라고 이름을 지었는데, 요리사들은 이름이 너무 추상적이라 헷갈린다고 불평했다. 손님이 주문한 메뉴가 구체적으로 어떤 요리인지 메뉴판만 보고는 확실히 알기 어렵다는 것이다.

3. REST 아키텍처


이제 위의 사례들을 통해 REST 아키텍처의 핵심 원칙들을 살펴보며, 식당의 문제점을 해결해보자.

요리사 -> API 개발자
음식 -> 자원(데이터)
여러 국적의 손님들 -> 여러 종류의 클라이언트 어플리케이션
여러 종류의 언어 -> 각 클라이언트 어플리케이션에 맞는 요청 방식
단골 손님 -> 로그인한 상태의 클라이언트
메뉴판, 메뉴 이름 -> API, URI
지점 -> 서버

1) 일관된 인터페이스 규칙으로 간결함 확보

식당 메뉴판에 여러 언어로 표기하는 대신, 공용어인 영어로만 작성한다면 어떨까?
이렇게 하면 메뉴 추가 작업이 간단해지고, 손님들도 필요하다면 스스로 번역기를 돌려 내용을 이해할 수 있다.

마찬가지로 주문의 결과로 나온 음식에도 국적에 관계없이 일관적으로 내놓는다면 어떨까?
일관적인 결과물이 나오기 때문에 요리사의 부담이 줄어들 것이다. 파키스탄 손님들도 필요하다면 주문 전에 돼지고기를 빼달라고 직접 요청을 할 것이다.

REST 아키텍처에서도 마찬가지로 “일관된 인터페이스” 를 강조한다. URI 설계와 HTTP 메소드 사용에 일관성을 유지하면, 개발자와 클라이언트는 API를 쉽게 이해하고 사용할 수 있다.

응답에도 일관적인 응답 형식을 유지하여 필요시 클라이언트가 직접 조작할 수 있게 하면 API 개발 시 더 쉽고 빠르게 개발할 수 있을 것이다.

2) 자체 표현 구조로 명확성을 증가

메뉴 이름을 정할 때 간결하면서도 명확한 규칙을 도입해보자.

예를 들어, “천사의 머릿결” 대신 “봉골레 스파게티”처럼 요리의 본질이 드러나는 이름을 쓰면 요리사와 손님 모두 혼란을 줄일 수 있다.

REST에서도 “자체 표현 구조(Self-Descriptive Messages)”를 권장한다.

API가 스스로 어떤 기능을 수행하는지 쉽게 알 수 있도록 설계하는 것이다.

URI와 HTTP 메소드만 보아도 요청이 무엇을 수행하는지 명확히 파악할 수 있어야 한다.

예:
GET /restaurants/123/menu → ID가 123인 레스토랑의 메뉴를 조회
POST /restaurants/123/menu → ID가 123인 레스토랑의 메뉴를 추가

이처럼 명확한 정보를 전달하면 커뮤니케이션 오류를 줄이고, API를 사용하는 개발자나 시스템이 빠르게 이해할 수 있다.

3) 무상태성으로 유연성 확보

손님의 얼굴을 직접 기억할 필요가 있을까?

회원 카드나 쿠폰을 만들어 손님에게 단골임을 증명하게 하면, 1호점과 2호점 모두 동일한 서비스를 제공할 수 있다.

REST에서 “무상태성(Stateless)” 원칙은 클라이언트의 상태 정보를 서버가 기억하지 않도록 한다. 즉, 클라이언트가 매 요청마다 자신이 누구인지, 어떤 상태인지 증명해야 한다.

예를 들어, 로그인 상태를 유지하려면 매 요청마다 인증 토큰을 포함해야 한다.

이 방식은 처음에는 번거로울 수 있지만, 서버를 단순화해 확장성과 유연성을 높인다.

손님의 정보를 기억하지 않아도 새로운 지점(서버)을 추가하거나 기존 지점(서버)을 교체할 수 있어 부하 분산이 쉬워진다.

4) 캐시 가능으로 성능 최적화

손님이 시킨 메뉴를 굳이 본점에 찾아오지 않고 집에서 직접 만들 수 있도록 밀키트를 제공하는건 어떨까?

손님이 본점에 찾아오지 않아도 주문하려는 음식을 집에서 직접 해먹으니 손님 입장에선 번거롭지 않아 좋고, 본점 입장에선 손님이 많아져 부하가 일어나는 것을 방지할 수 있다.

REST는 “캐시 가능(Cacheable)” 특성을 활용해 네트워크 요청을 줄이고 성능을 최적화한다.

동일한 요청에 대해 서버에서 동일한 응답을 반환할 수 있다면, 클라이언트는 이를 캐싱해 재사용할 수 있다.

예:
GET /menu 요청의 응답을 클라이언트가 캐시에 저장해, 동일 요청이 다시 들어오면 서버가 아닌 캐시된 데이터를 바로 사용한다.

이를 통해 서버 부하를 줄이고 클라이언트의 응답 속도를 높일 수 있다.

5) 클라이언트-서버 아키텍처로 역할 분리

이건 적절한 비유가 아니긴 한데..

식당은 식당대로, 손님은 손님대로 완벽하게 분리해야 한다.

계속해서 손님과 식당 사이에 역할을 다른 한 쪽이 더 맡으려고 한다면 서로의 독립성이 보장되지 않아 각각이 발전하려고 해도 발전할 수 없을 것이다.

REST는 “클라이언트-서버 아키텍처”를 사용해 역할을 명확히 분리한다.

서버는 자원의 저장과 처리를 담당하고, 클라이언트는 사용자 인터페이스와 자원 요청을 수행한다.

이 구조는 클라이언트와 서버가 독립적으로 발전할 수 있도록 돕는다.

6) 계층 구조로 확장성 강화

손님이 주문을 하고 요리를 받으며 먹고 나가는 과정에서 주문을 받는 웨이터, 요리를 하는 요리사, 계산을 하는 캐셔와 같이 식당의 시스템에서는 역할이 분리되어있다.

만약 손님의 수가 많아져서 주문량이 많아졌지만 요리의 강도는 크게 늘지 않았다면 요리사는 그대로 두고 웨이터만 더 뽑으면 된다.

REST의 “계층 구조(Layered System)”에서는 클라이언트와 서버 사이에 프록시 서버, 로드 밸런서, 캐시 서버를 두어 확장성을 강화한다.

여러 계층 중에 보완이 필요한 계층이 있으면 그 계층만 보완하면 된다.

클라이언트는 어떤 중간 서버를 거쳤는지 알 필요 없이 최종 데이터를 받기만 하면 된다.

이를 통해 시스템의 유지보수성이 높아지고, 보안이나 성능 최적화 등도 쉽게 구현할 수 있다.

4. REST API와 RESTful API


REST 아키텍처는 API를 제작할 때 반드시 지켜야할 불문율과도 같은 규칙이 아니라 경량화되고 효율적인 웹 서비스를 만들기 위한 권고사항, 가이드라인에 가깝다.

즉 REST 원칙을 따를지 안따를지는 오로지 API를 개발하는 개발자의 마음에 달려있다.

실제로 웹 개발을 해보면 REST의 원칙을 모조리 준수하기 쉽지 않은 경우가 많다.

그럼에도 불구하고 이러한 REST 원칙을 철저하게 준수하여 개발한 API를 RESTful API라고 하며 REST의 원칙의 일부만 준수한 경우에는 단순히 REST API라고 부를 수 있다.

즉, 모든 RESTful API는 REST API지만 모든 REST API가 RESTful하진 않는다.

일반적으로 빠르게 개발을 할 경우에 REST API를, 장기적으로 안정성이 필요한 프로젝트의 경우 RESTful API를 목표로 개발하는 것이 좋다.

profile
틀린_내용이_있다면_말해주세요.

0개의 댓글