HTTP
[API] 2. RESTFUL API - RESPONSE STATUS CODE + 객체 활용 응답 처리(데코레이터, 클래스)
foxlee
2021. 11. 1. 17:02
이전글 -
2020.11.01 - [Web/HTTP] - [API] 1. RESTful API란?
코드
status = {
"OK": 200, # GET - DATA OR EMPTY LIST
"CREATED": 201, # POST,
"ACCEPTED": 202, # POST - ASYNC
"NO CONTENT": 204, # DELETE, PUT
"BAD REQUEST": 400, # GENERAIL FAIL - CLIENT ERROR
"NO AUTH": 401, # LOGIN NEEDED
"FORBIDDEN": 403, # ADMIN ONLY
"NOT FOUND": 404, # NOT FOUND BY IDENTIFIER
"SEVER ERROR": 500, # SEVER ERROR
}
message = {
"kr": {
"OK": "성공", # GET - DATA OR EMPTY LIST
"CREATED": "생성", # POST,
"ACCEPTED": "요청 성공",
"NO CONTENT": "요청 성공", # DELETE, PUT
"BAD REQUEST": "잘못된 요청입니다.", # GENERAIL FAIL - CLIENT ERROR
"NO AUTH": "로그인이 필요합니다.", # LOGIN NEEDED
"FORBIDDEN": "접근 권한이 없습니다.", # ADMIN ONLY
"NOT FOUND": "원하시는 데이터를 찾지 못했습니다.", # NOT FOUND BY IDENTIFIER
"SEVER ERROR": "죄송합니다. 다음에 다시 시도해주세요.", # SEVER ERROR
},
"en": {
"OK": "Success", # GET - DATA OR EMPTY LIST
"CREATED": "Created", # POST
"ACCEPTED": "Request accepted",
"NO CONTENT": "Request has succeeded", # DELETE, PUT
"BAD REQUEST": "BAD REQUEST", # GENERAIL FAIL - CLIENT ERROR
"NO AUTH": "Please login first", # LOGIN NEEDED
"FORBIDDEN": "No permission", # ADMIN ONLY
"NOT FOUND": "Couldn't find what you want", # NOT FOUND BY IDENTIFIER
"SEVER ERROR": "Oops, something went wrong", # SEVER ERROR
},
}
# core/response.py
from core.constants import response
def return_404_for_no_auth(f):
def wrapper(*args, **kwargs):
user = None
# ..... 유저 세션 체크 로직
if user is None:
response = CustomeResponse()
return response.send(response_type="NO_AUTH")
return f(*args, **kwargs, auth_user=user)
# ..... wrapper 관련 코드
return wrapper
def return_500_for_sever_error(f):
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except:
# ..... 에러 처리 관련 코드
response = CustomeResponse()
return response.send(
response_type="SEVER_ERROR",
)
# ..... wrapper 관련 코드
return wrapper
class CustomeResponse:
headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Credentials": "True",
}
def send(
self,
result=None,
response_type=None,
lang="en",
additional_message=None,
):
status = response.status[response_type]
message = response.message[lang][response_type]
if additional_message is not None:
message += f"({additional_message})"
response_body = {"result": result, "message": message}
json_encode = json.JSONEncoder().encode
return Response(
json_encode(response_body),
status=status,
headers=self.headers,
mimetype="application/json",
)
from core.response import (
CustomeResponse,
return_500_for_sever_error,
return_404_for_no_auth,
)
@api.route("/<int:id_>")
@api.param("id_", "The action identifier")
class Action(Resource, CustomeResponse):
@return_500_for_sever_error
def get(self, id_):
if action := get_action(id_):
return self.send(response_type="SUCCESS", result=action)
return self.send(response_type="NOT_FOUND")
@api.doc("update action name")
@api.expect(parser_post, parser_auth)
@return_404_for_no_auth
@return_500_for_sever_error
def put(self, id_, **kwargs):
if get_action(id_):
if kwargs["auth_user"].is_admin():
args = parser_post.parse_args()
update_action(id_, args["name"])
return self.send(response_type="NO_CONTENT")
return self.send(response_type="FORBIDDEN")
return self.send(response_type="NOT_FOUND")
@api.doc("delete an action")
@api.expect(parser_auth)
@return_404_for_no_auth
@return_500_for_sever_error
def delete(self, id_, **kwargs):
if get_action(id_):
if kwargs["auth_user"].is_admin():
delete_action(id_)
return self.send(response_type="NO_CONTENT")
return self.send(response_type="FORBIDDEN")
return self.send(response_type="NOT_FOUND")
GET - 리소스 조회
- 리소스들을 전체를 가져오거나 특정 조건(필터)에 맞춰서 리소스들을 반환한다.
- 데이터가 없는 경우에는 빈 배열([])를 반환한다.
- 데이터가 있던 없던 성공 시 200
- 필수 조건 또는 조건 값 등의 맞지 않는 경우 400
- 특정 Identifier(식별자)로 조회하는 경우에 없으면 404 (NOT FOUND)
- 서버 에러 500
POST - 새로운 리소스 생성
- 새로운 리소스를 생성한다.
- 데이터가 정상적으로 생성 경우에는 리소스 아이디를 반환한다.
- 데이터가 정상적으로 생성되면 201, 비동기 작업 시 202
- 생성시 필요한 데이터가 없는 경우, 유니크한 값이 이미 존재하는 경우 등 400 (클라이언트에서 다른 값을 보내줘야함)
- 서버 에러 500
PUT - 이미 존재하는 리소스 업데이트
- 기존의 리소스를 업데이트한다.
- 특정 Identifier(식별자)로 없으면 404 (NOT FOUND)
- 기존에 데이터에 식별자 제외 전체를 업데이트 하는게 기본/ 예외는 있을 수 있음
- 업데이트 성공 시 204 - NO CONTENT 업데이트 실패시 400
- 서버 에러 500
- GET POST DELETE 으로는 어울리지 않는 작업들은 PUT으로 요청
DELETE - 이미 존재하는 리소스를 삭제
- 기존의 리소스를 삭제한다.
- 특정 Identifier(식별자)로 없으면 404 (NOT FOUND)
- 업데이트 성공 시 204 - NO CONTENT
- 서버 에러 500