API 설계 시 필요한 것
1. API End point의 설계
2. 요청 데이터, 응답 데이터의 설계
=> 문서화해서 프론트 개발자가 API를 사용하기 쉽도록 돕는 문서 : API 명세서
Application Programming Interface (API)
Application을 Programming 할 때 사용되는 인터페이스
Rest는 Representational State Transfer의 약자
- HTTP를 기반으로 하는 웹 서비스 아키텍처
- HTTP 메소드와 자원을 이용해 서로 간의 통신을 주고 받는 방법
API를 호출하기 위한 HTTP 메소드, URL을 포함 한 것
REST 방식으로 통신 할 때 필요한 작업을 표시하는 방법
POST는 새로운 자원의 생성 / 클라이언트가 특정 정보를 서버로 넘기고 그에 대한 처리 요청
클라이언트가 로그인에 필요한 정보를 서버로 넘겨 로그인에 대한 처리 요청 -> POST로 설계 (POST /user)
하지만 회원 가입도 POST /user 표현 가능
-> 굳이 타이트하게 RESTful한 API 설계를 따르지 않아도 됩
-> POST /users/login으로 만들어도 됨
*질문
회원 가입은 유저 한 명이 생기는 건데, POST /user/id 아닌가요?
POST /users/id 형태로 설계 하려면, 해당 유저를 식별할 값이 존재해야 하는데 회원가입 이후 유저가 생성되므로 유저를 식별할 값이 API 호출 시점에는 없다.
회원 탈퇴는 다음과 같이 설계 가능하다고 생각 할 수도 있다.
DELETE /users
그러나 추후 계정 복구를 고려한다면 DELETE 대신 PATCH를 사용 (user 테이블의 status를 active -> inactive로 변경)
PATCH /users
한 명의 교사가 여러 개의 과목을 강의 할 수 있을 때 교사와 교과목은 1:N 관계
/users/subjects
계층 관계는 교사 다음 교과목으로 잡고, URL상에 교사가 더 우선
만약 특정 교사의 교과목 목록을 보고 싶다면?
/users/id/subjects
게시글과 해시태그가 있을 때
게시글 하나 상세 조회 API
특정 게시글을 식별 할 수 있는 데이터를 서버에 넘겨야 함
-> path variable 사용
단 하나, 특정 대상을 지목할 때
/users/articles/id 처럼 id에 게시글의 식별 값을 넣어서 전달
GET https://???.com/users/articles/4
실제 API 명세서에는 아래처럼 표현
GET /users/articles/{articleId}
{}(중괄호)로 감싸는 부분은 path variable 의미
게시글 중 이름에 mine이 포함된 게시글을 조회하려 할 때 게시글의 수가 1개일 수도 있고 여러 개일 수도 있다. 이때 query string을 사용한다.
-> 주로 검색 조회 때 사용
GET /users/articles?name=mine
만약 전달 할 정보가 여러 개일 경우?
GET /users/articles?name=mine&owner=me
이런 식으로 &을 통해 쿼리스트링으로 전달하려는 값 여러개를 연결 할 수 있다.
POST의 방식의 경우 조회가 아닌 생성을 위해 사용하기도 하므로 URL에 해당정보를 노출하는 것은 굉장히 위험할 수 있다.
따라서 URL에 노출되지 않고 request body에 해당 데이터를 담을 수 있으며 json 형태 혹은 form-data 형태로 보내게 된다.
회원 가입 시 이름, 전화번호 닉네임 dl dlTdmf ruddn request body에 정보를 json으로 담아서 서버로 전송함
{
"name" : "김현수",
"phoneNum" : "010-0000-0000",
"nickName" : "hyeonsoo"
}
서버와 전송 시 메타데이터 즉, 전송에 관련된 기타 정보들이 담기는 부분이다.
body에 담기는 데이터 형식이 json인지 form-data인지 담기도 하고 데이터를 담을수도 있다.
닉네임 변경 API 설계의 경우
API Endpoint
PATCH /users/{userId}
request body
{
"nickname" : "hyeonsoo"
}
request header
Authorization : accessToken(String)
query string
필요없음