본문 바로가기

백엔드

API 개발하기(미니터 : 팔로우)

반응형
팔로우와 언팔로우 엔드포인트

 

실제 트위터와 마찬가지로 미니터에서 중요한 부분 중 하나가 또한 다른 트위터들을 팔로우(혹은 언팔로우)하고 팔로우하는 사용자들의 글과 사진을 타임라인에서 볼 수 있는 기능이다.

팔로우 혹은 언팔로우 하고 싶은 사용자의 아이디를 HTTP 요청으로 보내면 API에서 해당 요청을 처리하는 방식으로 구현할 것이다.

팔로우 엔드포인트에 전송할 JSON 데이터는 다음과 같다.

{
     "id"          : 1,
     "follow"     : 2
}

id 필드: 해당 사용자의 아이디, follow 필드: 팔로우하고자 하는 사용자의 아이디

 

 

언팔로우 엔드포인트에 전송할 JSON 데이터는 다음과 같다.

{
     "id"          : 1,
     "unfollow"     : 2
}

id 필드: 해당 사용자의 아이디, unfollow 필드: 언팔로우하고자 하는 사용자의 아이디

 

 

팔로우 엔드포인트 구현

user_id = int(payload['id'])

HTTP 요청으로 전송된 JSON 데이터에서 해당 사용자의 아이디를 읽어들인다.

 

user_id_to_follow = int(payload['follow'])

HTTP 요청으로 전송된 JSON 데이터에서 해당 사용자가 팔로우할 사용자의 아이디를 읽어들인다.

 

if user_id not in app.users or user_id_to_follow not in app.users: return '사용자가 존재하지 않습니다', 400

만일 해당 사용자나 팔로우할 사용자가 존재하지 않는다면 400 Bad Request 응답을 보낸다.

 

user = app.users[user_id]

app.users 딕셔너리에서 해당 사용자 아이디를 사용해서 해당 사용자의 데이터를 읽어들인다.

 

user.setdefault('follow', set()).add(user_id_to_follow)

사용자의 정보를 담고 있는 딕셔너리가 이미 "follow"라는 필드를 가지고 있다면 사용자의 "follow"키와 연결되어 있는 set에 팔로우하고자 하는 사용자의 아이디를 추가한다.

만일 이번이 처음 다른 사용자를 팔로우하는 것이라면 사용자의 정보를 담고 있는 딕셔너리에 "follow"라는 키를 emtpy set와 연결하여 추가한다.

 


그렇다면 해당 엔드포인트를 app.py에 추가하고 서버를 실행시켜 HTTP 요청을 보내보자!

http -v POST localhost:5000/follow id:=1 follow:=2

만약 사용자가 없다고 뜰 경우, 사용자를 추가해야 한다!

팔로우하는 사용자와 팔로우되는 사용자 총 2명의 사용자가 필요하다.

 

따라서

http -v POST localhost:5000/sign-up name=수지 email=csj8073@naver.com password=1234

이 코드를 2번 실행하여 2명의 사용자를 만들어주자!

 

 

다시 http -v POST localhost:5000/follow id:=1 follow:=2 코드 수행!

그러나 다음과 같은 오류(TypeError)가 발생한다. 

 

오류가 발생하는 이유는 팔로우하는 사용자 아이디들을 저장하는 자료구조로 사용하는 set를 파이썬 json 모듈이 JSON으로 변경하지 못하기 때문이다.

list는 JSON으로 변경될 수 있지만 set은 변경하지 못하므로 오류가 난다.

이 문제를 해결하기 위해서는 커스텀 JSON 엔코더를 구현해서 디폴트 JSON 엔코더에 덮어 씌워야 한다.

 

from flask.json import JSONEncoder
flask.json 모듈에 JSONEncoder 클래스를 임포트한다. JSONEncoder 클래스를 확장해서 커스텀 엔코더를 구현한다.

 

class CustomJSONEncoder(JSONEncoder):

JSONEncoder 클래스를 부모 클래스로 상속받는 CustomJSON Encoder 클래스를 정의한다.

 

def default(self, obj):

JSONEncoder 클래스의 default 메소드를 확장한다. default 메소드에서 set인 경우 list로 변경해주어야 한다.

 

if isinstance(obj, set): return list(obj)

JSON으로 변경하고자 하는 객체가 SET인 경우 list로 변경해서 리턴한다.

 

return JSONEncoder.default(self, obj)

객체가 set이 아닌 경우 본래는 JSONEncoder 클래스의 default 메소드를 호출해서 리턴하면 된다.

 

pp.json_encoder = CustomJSONEncoder

CustomJSONEncoder 클래스를 Flask 디폴트 JSON 엔코더로 지정해준다. 그리하면 jsonify 함수가 호출될 때마다 JSONEncoder가 아닌 CustomJSONEncoder 클래스가 사용된다.

 


위의 코드를 app.py에 추가하고 시스템을 다시 재시작시킨 후 follow 엔드포인트를 호출하자!

짜잔 성공적으로 http 응답이 오는 것을 확인할 수 있다!(200)

 


 

언팔로우 엔드포인트

user_id_to_follow = int(payload['unfollow'])

언팔로우할 사용자의 아이디를 HTTP 요청으로 전송된 데이터에서 읽어들인다.

 

if user_id not in app.users or user_id_to_follow not in app.users: return '사용자가 존재하지 않습니다'400

만일 해당 사용자나 팔로우할 사용자가 존재하지 않는다면 400 Bad Request 응답을 보낸다.

 

user = app.users[user_id]

app.users 딕셔너리에서 해당 사용자 아이디를 사용해서 해당 사용자의 데이터를 읽어들인다.

 

user.setdefault('follow', set()).discard(user_id_to_follow)

언팔로우하고자 하는 사용자의 아이디를 set에서 삭제한다. remove 메소드를 사용하지 않고 discard 메소드를 사용하는 이유는 remove의 경우 만일 없는 값을 삭제하려고 하면 오류를 일으키지만 discard 메소드는 삭제하고자 하는 값이 있으면 삭제를 하고 없으면 무시하기 때문이다.

 

 

 

반응형

'백엔드' 카테고리의 다른 글

데이터베이스(Database)  (0) 2021.08.10
API 개발하기(미니터 : 타임라인)  (0) 2021.08.08
API 개발하기(미니터 : 트윗)  (0) 2021.08.07
API 개발하기(미니터 : 회원가입)  (0) 2021.08.07
Do it! 모델 만들기  (0) 2021.08.06