
💡 학습 목표
1️⃣ RESTful한 API 설계 익히기
2️⃣ Spring Boot 프로젝트 세팅
이번 챕터에서는 API End point 설계와 요청 데이터 & 응답 데이터 설계를 학습하며, API를 큰 틀에서 설계해 보려고 한다!
API(Application Programming Interface) 란 무엇일까?
컴공이라면 많이 들어봤을 API는 클라이언트와 서버 간 통신에 필요한 인터페이스라는 사실 외에 더 많은 의미를 가진다.
우선 인터페이스는 어려운 것은 감추고 보다 쉽게 상호작용할 수 있도록 하는 시스템을 의미한다.
OSI 7계층에서 소켓을 Application Layer와 Transport Layer 간 데이터를 주고 받기 위한 인터페이스 역할로 표현하는 것처럼 인터페이스는 다양한 영역에서 사용된다.
REST는 REpresentational State Transfer의 약자로, HTTP를 기반으로 하는 웹 서비스 아키텍처를 의미한다.
즉, HTTP 메소드와 자원을 이용하여 서로 간의 통신을 주고받는 방법이라 할 수 있다.
REST 개념은 아래 블로그에 작성해두었다!
https://velog.io/@haewonny/spring-rest-api-01
REST API에서 API Endpoint 는 해당 API를 호출하기 위한 HTTP 메소드와 URL을 포함한다.
HTTP 메소드는 REST한 방식으로 통신할 때 필요한 작업을 표시하는 방법이다.
HTTP Method
1.GET: 조회
2.POST: 생성
3.PUT: 갱신(전체)
4.PATCH: 갱신(일부)
5.DELETE: 삭제
그리고 각각은 CRUD(생성, 조회, 갱신, 삭제)에 대응된다.
이외에도 HEAD, OPTIONS, CONNECT 가 있지만, 위 5가지의 메소드가 주로 사용된다!
RESTful한 API의 설계 규칙은 다음과 같다.
/users/id 와 같이 식별 값을 추가로 사용한다.실제 적용을 위해 예시를 보며 설계 방식을 이해해 보자!
회원가입, 로그인, 탈퇴를 위한 Endpoint 설계가 가장 애매한데, 특히 로그인의 경우가 RESTful한 API 설계를 따르기 어렵다.
로그인의 주체가 되는 대상은 사용자이므로 URI 상에 users (복수형)가 들어가야 하고, 클라이언트가 로그인에 필요한 정보를 서버로 전달하는 것이라 POST 메소드를 사용해야 한다.
그러나 회원가입 또한 POST /users 라고 표현할 수 있기 때문에 로그인은 POST /users/login 로 표현하면 된다.
이때 HTTP method와 필요한 자원에 대한 명시(URI)를 합쳐서 API Endpoint 라고 한다.
예를 들어, 웹 서비스를 하는 서버의 도메인 주소가 https://umc.com 인 경우 POST https://umc.com/users/login 로 요청을 해야 한다.
--
회원탈퇴의 경우에는 회원가입이 POST /users 였으니 러프하게 DELETE /users 로 설계하면 된다고 생각할 수 있다.
만약 요구사항이 다음과 같다면,
회원 탈퇴 시, 비활성 계정으로 만들고 일정 기간이 지나면 데이터베이스에서 유저 정보를 삭제한다.
추후 계정 복구를 고려하여 DELETE 메소드를 사용하면 안 된다.
따라서 비활성 계정으로 만들기 위해서는 user table의 status 를 active에서 inactive로 변경해야 하므로 PATCH 메소드를 사용해야 한다.
PATCH 메소드의 경우에는 회원 정보 수정 API에서도 사용될 수 있기 때문에, 특정 유저의 정보를 수정할 때는 id를 명시하여 PATCH /users/id 로 표현하면 좋다!
리소스 간 연관 관계가 존재하는 다음과 같은 요구사항이 있다고 가정하자.
한 명의 교사가 여러 개의 교과목을 강의할 수 있다.
이때 교과목의 목록을 조회하는 API를 설계한다면, 교과목은 교사와 1 : N 관계 를 가지므로 아래처럼 설계할 수 있다.
GET /users/subjects
교사가 여러 과목을 강의하므로 /(교사)/(교과목) 으로 계층 관계를 두어 표현했다.
추가적으로 특정 교사의 교과목 목록을 보고 싶다면 다음과 같이 설계하면 된다.
GET /users/id/subjects
이때 id는 Path Variable 인데, 이건 조금 뒤에 살펴볼 것이다! 🤗
만약, 특정 교사의 교과목 하나를 조회하는 API를 설계한다면 요구사항에 맞는 설계를 선택하면 된다.
특정 교사의 특정 교과목이 의미가 더 잘 전달된다면,
GET /users/id/subjects/id
특정 교과목이 더 의미가 잘 전달된다면,
GET /users/subjects/id
두 가지 방식으로 설계가 가능하다.
책 한 권에 해시태그 여러 개가, 해시태그 하나가 여러 책에 붙을 수 있다.
4주차의 도서 관리 앱 요구사항에서 책과 해시태그가 N : M 관계 라는 것을 확인할 수 있었다.
이런 경우에는 /books/hash-tags 와 /hash-tags/books 중에서 어떤 방식이 계층 관계를 파악하기 쉬울지 고민이 될 것이다.
이럴 땐, 비즈니스 로직상 더 중요한 대상을 계층 관계에서 앞에 두는 방법을 사용하면 된다!
위의 예시에서는 해시태그보다는 책이 더 서비스에서 중요한 역할이므로 아래처럼 API를 설계할 수 있다.
GET /books/hash-tags
이번에는 다음 키워드 4개에 대해 살펴볼 것이다.
- Path Variable
- Query String
- Request Body
- Request Header
이중 Path Variable 만 API endpoint에 포함된다.
그리고 위의 키워드들은 모두 API를 세부적으로 설계하기 위해 사용된다.
게시글 하나를 상세 조회할 수 있다.
위의 요구사항을 구현하기 위해서는 게시글 하나 상세 조회 API 를 설계해야 한다. 이때 특정 게시글에 대한 조회임을 서버에 전달하기 위해서는 Path Variable 을 사용해야 한다.
즉, 특정 대상을 지목하기 위해 /users/articles/id 처럼 id 에 게시글의 식별 값을 넣어 전달해야 한다.
이때 id는 데이터베이스에서 게시글의 기본키가 될 것이다.
실제 API 설계에서는 다음과 같이 표현할 수 있다!
GET /users/articles/{articleId}
게시글 이름에 특정 글자가 포함된 게시글을 조회할 수 있다.
위의 요구사항을 구현하기 위해서는 게시글이 여러 개일 수도 있다는 점을 고려해야 한다. 이때 검색 조회 기능을 구현하기 위해서는 Query String 을 사용해야 한다.
즉, 게시글 중 이름에 umc가 포함된 게시글을 조회하기 위해 다음과 같이 요청을 보낼 수 있다.
GET /users/articles?name=umc
그리고 전달할 정보가 여러 개라면 & 을 통해 쿼리 스트링으로 전달하려는 값을 여러 개 연결할 수 있다.
GET /users/articles?name=umc&owner=hh
여기서 주의할 점은 Query String은 API endpoint에 포함되지 않기 때문에 실제 엔드 포인트는 다음과 같이 설계해야 한다!! 🌟
GET /users/articles
지금까지 GET 방식에 대해 살펴봤다면, 이번엔 POST 방식의 경우 어떻게 서버로 데이터로 전달하는지 살펴볼 것이다.
POST 는 url에 데이터를 포함하여 정보를 노출시킨다면 위험할 수 있기 때문에, Request Body 를 사용하여 데이터를 담아야 한다.
그리고 Request Body에 데이터는 json 형태 또는 form-data 형태로 포함될 수 있다.
예를 들어, 회원가입 시 세 가지 정보(이름, 전화번호, 닉네임)가 필요하다고 가정하면 Request Body에 json 형태로 데이터를 담아 서버에 전달할 수 있다.
{
"name" : "이해원",
"phoneNum" : "010-1234-5678",
"nickName" : "루나",
}
Request Header 에는 전송에 관련된 기타 정보들이 담기는 부분이다.
대표적으로 로그인이 되었다는 것을 알려주기 위한 토큰을 헤더에 담아 보낸다.
최용욱님의 [UMC Server Workbook]을 기반으로 작성했습니다.