간단한 데모 버전의 서비스를 완성했다. 우리가 만들고자 하는 서비스의 모든 기능들은 없지만, 간단한 기능들이 구현되었다. 이를 위해 백엔드, 프론트엔드를 완성하였고, 백엔드 Api와 프론트엔드가 연동이 가능하도록 하였다.
백엔드와 프론트엔드로 나누어 이번 Iteration 동안 한 일은 다음과 같다.
- 모델을 수정하였다. User의 정보를 담는 Profile 모델과 가장 기본이 되는 Meeting 모델의 다양한 필드들을 만들었다. 모임을 검색하기 위한 Search를 구현하고자 Tag를 만들었다. 또한 Meeting에 참여하기 위한 Membership을 만들어서, Meeting에 참여하게 되면 Membership 객체가 만들어져서 Meeting을 참조하도록 하였다. 마지막으로 내가 관련된 모임에 변화가 생길 경우 알림을 주기 위한 Notification 모델을 만들었다. 이 모델은 관련된 데이터에 변화가 생기면 자동으로 생성된다.
- 백엔드 Api를 위한 Url을 확정하였다. 이 내용들은 Design & Planning 문서를 토대로 작성되었다. 프론트엔드가 백엔드와 통신하기 위한 Url은 다음과 같다.
'urlpatterns = [
path('signin/', views.Login), # POST username and password to receive token and user info
path('signup/', views.Register.as_view()), # Sign Up through POST
path('user//', views.ProfileDetail.as_view()),
path('user//meetings', views.UserMeetingList.as_view()),
path('meetings/', views.MeetingList.as_view()),
path('meetings//', views.MeetingDetail.as_view()),
path('meetings//join/', views) #POST, PUT, DELETE
path('search/', views.SearchResult.as_view()), #GET
path('comment/', views.CommentList.as_view()), # POST, should be here
path('comment//', views.CommentDetail.as_view()), #POST, PUT, DELETE
path('notification//', views.NotificationDetail.as_view()) #GET, DELETE
]`
- 백엔드 Api를 구현하였다.
각각의 Url에 Request가 들어올 경우 Response를 전달해주기 위한 Api를 구현하였다. Backend의 views.py를 수정하는 것이 주된 업무였으며, permission.py와 serializer를 이용하였다. Api 구현은 Generic을 최대한 활용했으며, 각각의 과정에서 Authentication을 이용한 Validation도 진행하였다. 자세한 내용은 [https://github.com/thunderlink/ThunderFish/blob/master/backend/server/views.py](url) 에서 확인할 수 있다.
- 회원가입과 로그인을 구현하였다.
Token을 이용한 회원가입(Register, Sign Up)과 로그인(Sign in)을 구현하였다. Authentication을 하기 위한 Token을 Frontend에 Response로 던져 줌을 통해서 Permission을 부여하기 위한 작업을 하였다. 또한, 추후에 카카오 등의 소셜 로그인을 구현하기 위한 초석을 다졌다.
그러나, 특수한 경우에 로그인 정보를 제대로 받아 오지 못한 경우가 있어, 시연 전까지 해당 부분을 수정할 예정이다.(issue #35)
자세한 코드는 아래에 있다. 가장 일반적인 방법인 Post를 사용하였다.
`@csrf_exempt
@api_view(["POST"])
@permission_classes((AllowAny,))
def Login(request):
username = request.data.get("username")
password = request.data.get("password")
if username is None or password is None:
return Response({"error": "Error!"}, status=HTTP_400_BAD_REQUEST)
user = authenticate(username=username, password=password)
if not user:
return Response({"error", "Invalid Credentials"}, status=HTTP_404_NOT_FOUND)
token, _ = Token.objects.get_or_create(user=user)
key = {'token': token.key}
profile = Profile.objects.get(pk=user.id) # get user's profile
ret = {**ProfileSerializer(profile).data, **key} # Merge two dictionaries
return Response(ret, status=HTTP_200_OK)
# Post Works
# http -v POST http://127.0.0.1:8000/signin/ username="zx" password="123"
class Register(generics.ListCreateAPIView):
permission_classes = (AllowAny, )
def post(self, request, *args, **kwargs):
data = request.data
user = User.objects.create_user(username=data['username'], password=request.data['password'])
Profile.objects.create(user_id=user.id, gender=data['gender'], nickname=data['nickname'], name=data['name'])
return Response(status=HTTP_200_OK)
# http -v POST http://127.0.0.1:8000/signup/ username="zxc" password="123" gender="1" nickname="cxz" name="zxc zxc"`
- 대부분의 Component를 완성시켰다. Component 들의 디자인과 기능을 구현하였으며, Router 등의 사용으로 효율적인 인터페이스가 구현되도록 하였다. Component마다 필요한 내장 스테이트와 함수를 구현하였다. 자세한 내용은 [https://github.com/thunderlink/ThunderFish/tree/master/frontend/src/components](url) 에서 확인할 수 있다.
- Action과 Reducer를 구현하였다. State 관리와 백엔드 Request를 만들기 위한 Action들의 종류를 결졍하고, 이를 구현하였다. 큰 Component 별로 필요한 State를 구분하였으며, Action도 구분하였다. Action은 크게 Http Request를 날리기 위한 액션과, Response의 결과로 State를 수정하기 위한 액션으로 나누었다. 각각의 Action 마다 State를 어떻게 바꿀 지 Reducer 함수를 구현하였다.
- Saga를 이용해서 백엔드와 연결하는 작업을 했다. 백엔드에서 로그인 시 구현한 토큰을 이용해서 다양한 백엔드 Api를 호출했다. 자세한 코드는 [https://github.com/thunderlink/ThunderFish/blob/dw_frontend/frontend/src/services/api.js](url)에 있다.
2. Testing을 진행하였다.
- Travis CI에 우리 팀의 프로젝트를 연동하여, Push 할 때마다 백엔드 테스트코드와 프론트엔드 테스트코드가 실행되도록 하였다.
자세한 결과는 [https://travis-ci.com/thunderlink/ThunderFish](url)에서 전체공개로 확인할 수 있다.
- Python Test를 구현하였다. 구현한 테스트 결과는 위의 Travis에서 확인이 가능하며, 코드는 [https://github.com/thunderlink/ThunderFish/blob/master/backend/server/tests.py](url)에서 확인이 가능하다. 여기서 테스트 한 케이스들은 다음과 같다.
1. 처음에 비어있는 model들 확인
2. Login을 실행하고, meeting 잘 생기는지 확인 ( post, put, delete)
3. user 정보 잘 받아지는지 확인
4. comment 잘 생기는지 확인
5. meeting join이 잘 되는지 확인 ( post, put)
6. search가 잘 되는지 확인 (tag 포함하는지)
7. notification 잘 생기고 지워지는지 확인
8. signin & signup 되는지 확인.
9. Permission 문제 등 Validation 확인
- Jest를 이용한 React Component Test와 Coverage Test를 진행하였다. 테스트 결과는 위의 Travis 사이트에서 확인할 수 있다. 프론트엔드 테스트의 경우, 자세한 테스팅은 깊은 수준의 테스팅보다 Shallow 테스팅을 진행했으며, 콤포넌트 별로 렌더링 결과를 테스트 하는데에 그쳤다.
프로젝트가 진행되며, 더 많은 부분을 Snapshot과 Matcher로 체크할 계획이다.
이번 Iteration에서 한 일 ::
이번 Iteration에서 한 일은 크게 다음과 같다.
백엔드와 프론트엔드로 나누어 이번 Iteration 동안 한 일은 다음과 같다.