개발을 해본 사람들은 API를 무조건 알것이다.
근데 무슨 뜻인지 정확히 아는가!
API
API는 Application을 Programming 할 때 사용되는 인터페이스이다.
(인터페이스는 간단히 말해서, 어려운 것은 감추고 보다 쉽게 상호작용할 수 있도록 해주는 것들을 의미한다.)
한마디로, API는 소프트웨어 간의 상호 작용을 가능하게 하는 규칙과 프로토콜의 집합이다.
이를 통해 서로 다른 소프트웨어 시스템들이 데이터를 주고받는 기능을 사용할 수 있게 하는 것이다.
REST API
REST는 Representational State Transfer의 약자로 HTTP를 기반으로 하는 웹 서비스 아키텍처를 의미하며, HTTP 메소드와 자원을 이용해 서로 간의 통신을 주고받는 방법이다.
REST: 웹 서비스의 설계 원칙과 패턴을 의미
REST API: 이 원칙을 따르는 웹 API
REST API 주요원칙
1. 자원(Resource): REST는 모든 것을 자원으로 취급한다. 자원은 URI(Uniform Resource Identifier)로 식별된다.
2. 표현(Representation): 자원은 다양한 형식(JSON, XML, HTML등)으로 표현될 수 있다. REST API는 일반적으로 json 형식을 사용하여 데이터를 주고 받는다.
3. 상태 없는 상호 작용(Stateless): 각 요청은 완전하고 독립적이어야 한다. 서버는 이전 요청의 상태를 기억하지 않는다. 클라이언트는 필요한 모든 정보를 각 요청에 포함시켜야 한다.
4. 표준 HTTP 메서드: HTTP 메소드는 REST방식으로 통신 할 때 필요한 작업을 표시하는 방법이다.
대표적으로 5가지가 있다.
- GET : 조회
- POST : 생성
- PUT : 갱신(전체)
- PATCH : 갱신(일부)
- DELETE : 삭제
5. 계층 구조(Layered System): REST는 클라이언트와 서버 사이에 여러 계층(ex. 캐시, 프록시)을 둘 수 있다.
6. 캐시 가능(Cacheable): 서버 응답은 캐시 가능해야 하며, 클라이언트는 캐시된 데이터를 사용할 수 있다. 이를 통해 성능을 향상시킬 수 있다.
API Endpoint: 클라이언트와 서버 간의 상호작용을 가능하게 하는 웹 서비스의 특정 URL
REST API에서 API Endpoint는 해당 API를 호출하기 위한 HTTP 메소드, 그리고 URI(ex. /users)을 포함한다.
RESTful API Endpoint의 설계 규칙
1. URL에 동사가 포함이 되어선 안된다
2. URL에서 단어의 구분이 필요한 경우 -(하이픈)을 이용한다
3. 자원은 기본적으로 복수형으로 표현한다
4. 단 하나의 자원을 명시적으로 표현을 하기 위해서는 /users/id와 같이 식별 값을 추가로 사용한다
5. 자원 간 연관 관계가 있을 경우 이를 URI에 표현한다
회원가입, 로그인, 탈퇴로 RESTful한 endpoint을 알아보자!
회원가입, 로그인
회원가입과 로그인은 주체가 되는 대상은 사용자이므로 url상에 users가 들어간다고 생각이 든다.
그래서 회원가입과 로그인의 경우 POST /users로 표현이 될 수 있는데 두 엔드포인트가 겹치면 안되기에, 이런 경우에는 너무 타이트하게 RESTful한 API 설계를 따르려고 하지 않아도 된다.
따라서 회원가입은 POST /users 혹은 POST /users/singup, 로그인은 POST /users/login으로 만들어도 좋다.
의문이 드는 점🤔: 회원 가입은 유저 한 명이 생기는 건데, POST /users/id가 아닌가?
POST /users/id의 형태로 설계를 하려면, 해당 유저를 식별할 값이 존재해야 하는데 회원가입 이후에서야 해당 유저가 생성이 되기에, 유저를 식별할 값이 API 호출 시점에는 없다. 따라서 이런 경우는 POST /users/id와 같은 설계가 불가능하다!
위처럼 HTTP 메소드, 그리고 필요한 자원에 대한 명시를 한 URI를 합쳐 API Endpoint라고 하며 웹 서비스 하는 서버의 도메인 주소가 https://tistory/users/login 이렇게 요청을 할 경우 로그인이 되는 것이다.
회원탈퇴
회원탈퇴는 DELETE /users 라는 생각이 들 수 있다. 물론 틀린 방법이 아닌데 회원 탈퇴 시 곧바로 데이터베이스에서 삭제가 아니라, 비활성 계정으로 만들고 추후 계정 복구를 고려한다면 DELETE로 설계를 하면 안된다. 이런 경우 데이터베이스에서 사용자 테이블에 status를 activte에서 inactivite로 변경하는 것이기에 일부 수정인 PATCH를 활용해야 한다.
PATCH /users
그런데 이 경우 회원 정보 수정 API까지 고려해서 설계를 해야 한다. 회원 정보 수정 API 역시 닉네임 등 일부 정보만 수정하는 것이기에 PATCH를 사용하며, PATCH /users로 설계가 가능하다 보통 그래서 회원 정보 수정은 PATCH /users/id로 특정 유저의 정보 수정임을 명시적으로 표현하고, 회원 탈퇴는 PATCH /users로 표현하기도 한다.
(허나 프론트엔드 개발자가 헷갈려 할 수도 있기에 회원 탈퇴의 경우 /users 뒤에 추가적인 정보를 더해 설계를 할 수도 있다.)
이렇듯, API 설계에는 절대적인 정답은 없고, 위에서 나열한 5개의 규칙을 지키되 요구 사항에 따라 피치 못한 경우는 무조건 규칙을 따르지 않아도 된다 결국 프론트엔드 개발자가 API 설계를 보고 이해할 수 있으면 된다!
회원가입, 로그인, 탈퇴, 수정 등은 users로 모두 리소스가 1개였다.
이제 리소스 간 연간 관계가 있는 경우들을 알아보자
리소스 간 연관 관계가 있는 경우 (중첩된 URL 경로)
1:N관계 API 설계
예를 들어 교과목이 한 명의 사용자(교사)가 여러 개의 교과목을 강의 할 수 있다고 하고, 교사와 교과목이 1:N 관계인 경우 이런 상황에서 교과목의 목록을 조회하는 API를 설계한다고 가정하자.
교과목은 교사와 1:N 관계를 가지므로, 아래처럼 설계할 수 있다.
/users/subjects
이런 식으로 교사가 여러 개의 과목을 강의하기에 계층 관계는 교사 다음 교과목으로 잡고 uri상에 교사가 더 계층 관계 상 우선이 된다는 것을 표현할 수있다
만약 특정 교사의 교과목 목록을 보고 싶다면 어떻게 할 수 있을까?
/users/id/subjects
이렇게 설계가 가능하다
만약 교과목 하나 단건 조회 API를 설계한다면?
/users/id/subjecys/id
혹은
/users/subjects/id
N:M 관계 API 설계
예를 들어, 게시글과 해시태그의 경우를 알아보자
두 가지 API 중에 고민이 될 수도 있다
/articles/hash-tags
/hash-tags/articles
이런 경우는 비지니스 로직상 더 중요한 대상을 계층 관계에서 앞에 두는 방법이 있다
사실 위의 경우는 직감적으로 해시태그는 부수적인 것이고, 게시글이 서비스에서 더 중요한 역할을한다는 것을 쉽게 느낄 수 있다. 이런 경우는 /articles/hash-tag 이렇게 설계가 가능하다
(이처럼 API 설계에서도 기획의 요구 사항이 영향을 끼치므로 반드시 PM, 프론트 개발자와 많은 소통을 하며 설계를 해야한다,,)
API 요청을 구성하는 요소들
세부적인 API 설계하는 방법
- path variable
- query string
- request body
- request header
위의 4개 중 API endpoint에 포함이 되는 것은 path variable 하나 뿐이다. 엔드포인트 자체는 URL 경로와 HTTP 메서드로 구성되며, Path Variable은 URL 경로의 일부로 포함될 수 있다. 하지만 Query String, Request Body, Request Header는 API 요청의 다른 구성 요소로, 엔드포인트의 정의에 직접 포함되지 않는다.
예를 들어 회원 가입을 한다고 하자. POST /users 정도로 엔드포인트 설계는 끝이 난다. 그러나 위의 정보 만으로 부족한 것이 있다. 회원 가입이란 회원 정보를 새로 저장하는 건데, 무슨 정보를 저장하는지 엔드 포인트 만으로는 실제 동작 수행에 필요한 정보를 표현할 수 없다. 이런 경우 바로 위의 4가지를 사용하게 된다.
1. Path Variable: 리소스를 식별하는 변수
이런 경우가 있을 수 있다. 게시글 하나 상세 조회 API
여기서 어떻게 특정 게시글임을 서버에게 전달이 가능할까?
다시 말해, 서버에게 어떻게 원하는 게시글을 식별할 수 있는 데이터를 넘길 수 있을까?
이런 경우 path variable을 사용한다 /users/articles/id 처럼 id에 게시글의 식별 값을 넣어서 전달하게 된다. 따라서 실제로는 아래와 같다. GET https://umc.com/users/articles/4 ← 저 4에 주목!
여기서 저 4가 데이터베이스 상에서 게시글의 기본키라는 것을 캐치 한다면 잘 이해한 것이다.
따라서 /users/articles/id에서 id는 진짜 문자 그대로 id가 아니라 게시글의 식별 값을 의미한다.
따라서 실제 API 명세서에는 아래처럼 표현한다.
GET /users/articles/{articleId}
2. Query String: 추가 매개변수를 전달
게시글 중 이름에 sol이 포함된 게시글들을 조회하려고 할 때, 이런 경우 1개가 될 수 있고 여러개가 될 수도 있다. 따라서 단 하나만 조회하는 path variable을 사용하는 것이아니고 query string을 활용하는 것이다. 쿼리 스트링은 보통 검색 조회, 필터링, 페이지네이션 때 사용이 되며 따라서 GET 요청에서 사용이 된다
GET/ users/articles?name=sol
GET/ users/articles?name=sol&owner=sol
위처럼 name이 sol라는 것을 전달 할 수 있고 만약 전달 할 정보가 여러 개일 경우 아래와 같이 &를 통해 쿼리 스트링으로 전달을 하려는 값을 여러 개 연결 할 수 있다. 주의할 점은, 쿼리 스트링은 API 엔드 포인트에 포함이 되지 않기에 엔드 포인트 자체는 GET /users/articles 이렇게 설계를 해야 한다.
3. Request Body: POST, PUT, PATCH 요청에서 데이터를 전달하기 위해 사용
POST 방식의 경우는 어떻게 서버로 데이터를 전달할까? POST는 조회가 아닌, 생성을 위해 사용하기도 하며 url에 해당 정보들을 노출하는 것은 굉장히 위험할 수 있다. 따라서 url에 노출이 되지 않고 request body에 해당 데이터를 담을 수 있으며 보통 json의 형태 혹은 form-data 형태로 보내게 된다.
예를 들어 회원 가입 시 아래의 정보가 필요하다.
1. 이름
2. 전화번호
3. 닉네임
이럴 경우 request body에 위의 정보를 json으로 담아서 서버로 전송하게 된다
{
“name” : “라또”,
“phoneNum” : “010-1111-2222”,
"nickName" : "sol",
}
4. Request Header: 요청에 대한 추가 정보를 전달
request header는 서버와 전송 시 메타데이터, 즉 전송에 관련된 기타 정보들이 담기는 부분이다. body에 담기는 데이터의 형식이 json인지 아니면 form-data인지를 담기도 하고 혹은 데이터를 담을 수도 있다. 대표적으로 로그인이 되었다는 것을 알려주기 위해 토큰을 헤더에 담기도 한다
API 설계 예시
예를 들어 닉네임 변경(사용자 정보 변경) API에 대한 설계를 한다고 할 경우 아래와 같은 정보를 명시할 수 있다.
API Endpoint: PATCH /users/{userId},
Request Body가 아래와 같다면
{
"nickname" : "sol"
}
Request Header는 아래와 같을 것이다.
Authorization: accessToken (String)
accessToken은 로그인 된 사용자가 나 로그인이 된 상태야 하고 알려주는 것으로 보통 Authorization이라는 키에 대한 값으로 헤더에 담아서 서버로 보내주게 된다.
API, REST API, Endpoint를 설계하는 방법, 구성하는 요소 4가지 등 모두 알아보았다. 😆
무엇보다 협업할 때는 백엔드 개발자 혼자 정하는 게 아니라 많은 얘기를 한 후 모두가 알기 쉽게 엔드포인트를 설계해야 겠다고 생각이 들었다!
미션 🔥
홈 화면, 마이 페이지 리뷰 작성, 미션 목록 조회(진행중, 진행 완료), 미션 성공 누르기, 회원 가입 하기(소셜 로그인 고려 X) 위의 기능을 구현하는데 필요한 API들을 설계하여API Endpoint, Request Body, Request Header, query String, Path variable 이 포함된 간단한 명세서를 만들기!
1. 회원가입 하기 (소셜 로그인 X)
API EndPoint: POST /users
Request Body:
{
"name": "sol",
"email": "sol@ewhain.net",
"password": "password"
}
Request Header: Content-Type: application/json
2. 홈화면 (내가 받은 미션)
API EndPoint: GET /home
Request Header: Authorization: Bearer {token}
3. 마이 페이지 리뷰 작성
API EndPoint: POST /reviews
Request Body:
{
"store_id": 1,
"member_id": 1,
"body": "맛있어요",
"score": 4.5
}
Request Header: Authorization: Bearer {token}, Content-Type: application/json
4. 미션 목록 조회(진행중, 진행 완료)
API EndPoint: GET /missions
Query String: status=ongoing or status=completed
Request Header: Authorization: Bearer {token}
5. 미션 성공 누르기
API EndPoint: POST /missions/{mission_id}/complete
Path Variable: mission_id:1
Request Header: Authorization: Bearer {token}
프로젝트 세팅 완료
'IT 동아리 > UMC' 카테고리의 다른 글
[Chapter 11] 무중단 CI/CD (Github Action+AWS Elastic Beanstalk) (0) | 2024.06.28 |
---|---|
[Chapter 7] JPA를 통한 엔티티 설계, 매핑 & 프로젝트 파일 구조 이해 (0) | 2024.05.24 |
[Chapter 5] 실전 SQL - Query를 작성하는 방법 (1) | 2024.05.10 |
[Chapter 3] Web Server & Web Application Server(WAS), Reverse Proxy (1) | 2024.05.02 |
[Chapter 2] AWS (VPC & Internet & Gateway & EC2) (2) | 2024.04.10 |