본문 바로가기
파이썬/파이썬 플라스크

ep 8. Flask-RESTful 로 Car CRUD api 구축하기

by L_SU 2022. 8. 29.

플러거블 뷰란?

플라스크는 데코레이터와 함수를 이용해 API를 작성하는데 이것을 함수 기반 뷰라고 한다. 하지만 django의 영향을 받아 만들어져 데코레이터를 이용하지 않는 view가 플러거블 뷰이다.

 

함수 기반 뷰

다음과 같이 /shop 주소로 GET 요청을 처리하는 api가 있다. 이를 플러거블 뷰로 변형시켜보면 아래와 같이 된다.

플러거블 뷰

위에서 설명한 차이를 알 것 같지 않은가? 아래에 간단히 CRUD를 구현해보며, 좀 더 정확하게 알아보자

 

먼저 위처럼 코드 작업을 하기 위해서 다음과 같은 내용을 requirements.txt에 입력해주고, pip install -r requirements.txt 로 install 해준다.

이제 한번 동물들을 데리고 조회, 생성, 수정 삭제등 CRUD api를 구현해보겠다.

app.py에 다음과 같이 틀을 짜줬다. 동물들을 데리고 만들어 볼 것이라고 했기 때문에 클래스 명을 Animal로 설정해줬고, Resource를 상속받고 있는데 Resorce는 MethodView를 상속받아 만들어졌고 또, 이 MethodView는 View를 상속받아 만들어졌다. 그 결과 get(), post(), put() 등의 메소드를 정의해 GET, POST, PUT과 같은 요청처리가 가능하다. 또 응답은 flask-restful이 json으로 할 수 있게 해줘서 이리도 간편하게 api구현이 가능한 것이다.그 위의 animals는 원래라면 데이터 베이스에 데이터가 저장되어야 하지만 이번 실습의 초점은 api 구현 이기 때문에 파이썬 리스트로 저장해주기 위함이라고 이해해주면 좋을 것 같다.

 

이제 GET 요청부터 처리해보겠다.

다음과 같이 코드를 짜줬는데, 내용을 살펴보면 name으로 인자를 받아 animals에서 이름이 같은 객체가 있는지 찾고, 있을 시 이를 리턴해주는 것이다. 이렇게 해주면, 우리가 주소/animal/<name> 처럼 요청을 보냈을 때 그 동물의 상세 정보를 확인 할 수 있게 되는 것이다.

다음으로 post 코드를 짜줬다. 이름의 경우 주소에 있는 정보를 받아 넣어주고 age는 내가 입력한 값을 data로 받아 age에 넣어주는 것이다. 마지막으로 append로 리스트에 넣어주고 새로 입력한 정보(animal)를 출력해준다.

 

class 밖에 마지막으로 아래와 같은 소스를 넣어주면 주소에서 정상 작동하는 것을 확인할 수 있다.

Animal class로 뒤의 주소를 응답해준다고 생각하면 편하다. 아래는 디버그 모드를 활성화한 것으로 원래대로라면 코드를 수정하고, 서버를 재기동 해야 하지만 아래의 코드를 넣어주면 우리가 코드를 수정할 때 서버가 자동으로 재기동을 한다고 생각하면 편하다.

이제 테스트를 위해 animals list에 다음과 같이 임의의 값을 넣어 준다.

그리고 아래와 같이 name을 넣어주고 GET 요청을 보내주면 된다.

그럼 위와 같이 cat에 대한 정보가 제이슨으로 응답하는 것을 확인할 수 있다. 이번엔 POST 요청을 보내보자.

다음과 같이 age에 대한 정보만 넣어주고 POST 요청을 보내주게 되면 아래와 같이 name 데이터는 주소에서 가져오기로 했기 때문에 정상적으로 name과 age의 값이 들어간 것을 확인할 수 있다.

확실하게 GET요청으로 변환해 한번더 요청을 보내보면 아래와 같이 정보가 잘 출력되는 것을 확인할 수 있다.

다음으로 수정을 구현해보겠다.

 

put으로 오는 요청을 처리하면 되는데 name을 받아서 이미 존재하는 이름이면 수정한 값이 업데이트 되는 것이고, 이름이 존재하지 않다면 새로 추가해주는 코드라 생각하면 된다.
여기서 animal로 받을때 next()와 filter()를 사용했는데 filter()는 조건문이라 생각하면 된다. lambda x로 받은 name과 animals안에 있는 아이템의 name과 같은지 확인한다. 이걸 next()로 반복해 없을 경우 None을 기본값으로 주는 것이다. 

 

다음과 같이 PUT 요청을 보내게 되면 우리는 이미 cat이란  name을 가진 아이템을 만들어놨기 때문에 아래와 GET 요청을 보냈을 때 수정된 모습을 확인할 수 있다.

 

다음으론 삭제를 구현해보겠다!

아래와 같이 코드 작업을 해주면 된다

둘 중 원하는 방식대로 코드를 짜주면 되는데 위에 주석친 코드같은 경우 주소의 name값으로 animal을 받아주고, animals를 주소의 이름을 제외하고 재정의 한다. 이러면 자연스럽게 리스트 안에 주소와 같은 이름이 있다면 그 아이템만 제외하고 리스트가 만들어질 것이다. 그리고 만약 주소의 이름과 리스트 안의 아이템 중 이름이 같다면 잘 삭제 됐다는 문구와 함께 200을 반환 하고 주소에 입력된 이름이 존재하지 않는다면 없다는 문구와 함께 404를 반환하는 코드이다.

반면에 아래의 코드의 경우 animal에 주소 이름과 animals 리스트 안의 아이템의 이름과 비교해 값을 넣어주고, animal에 값이 들어가지 않았다면 없다는 문구와 함께 404를 리턴해주고 존재한다면 animals안에 이름이 같은 아이템을 삭제해주고 200을 리턴해준다.

여기서 주의할 점은 del()외의 삭제 함수들의 특징을 잘 알고 사용해야 된다. 비슷한 역할을 하는 pop(), remove(), clear()가 존재하는데 pop은 지정한 위치값을 삭제후 그 값을 취득하고, remove()는 지정한 값을 삭제하지만 만약 중복되는 값이 있다면 맨 앞을 삭제한다. 우리가 지금 하는 실습에 있어선 같은 이름은 생성되지 못하게 할 것이지만 만약 중복을 가능하게 한다면 엉뚱한 값이 삭제 될 수도 있는 것이다! 이런 특성을 알고 사용하는 게 매우매우 중요하다.

 

이렇게해서 CRUD를 모두 구현해줬으니 이번엔 조금 조건을 추가하는 작업을 해보겠다.

먼저 GET부터 현재 하나하나의 동물의 정보는 볼 수 있으나 전체 동물의 리스트는 볼 수 없다. 이를 위해 아래와 같이 작업해주겠다.

새로운 함수를 만들어서 animals 안에 데이터들이 정렬되도록 코드를 짜줬다.

 

다음으로 POST 동물을 새로 추가하는 것은 좋지만 중복되는 동물이 없도록 같은 이름이 있으면 만들지 못하게 작업해주겠다.

다음과 같이 코드를 작업했다. 이 역시 animal로 name을 받아 비교해보고 이미 있다면 메시지와 함께 400을 리턴, 없다면 생성해주고 201을 리턴해주는 코드이다.

 

추가로 PUT 요청은 두가지 경우의 수를 처리하기에 어떻게 처리 됐는지 알려주기 위해 HTTP상태코드를 다르게 리턴해줬다. 숫자 코드의 의미는 HTTP 상태코드에 대한 정보를 추가로 열람해보는 것을 추천한다.

 

정말 마지막으로 animal 상세 정보에 대한 요청이 왔을 때 그 동물이 존재하지 않는다면 404와 함께 존재하지 않는다는 문구를 리턴해줬다.