원티드 1주차 기업 과제 : Aimmo Assignment Project ✅ Aimmo 기업 과제입니다.
- Team 소개
- 과제 내용
- 서버 주소
- 기술 환경 및 Tools
- 프로젝트 구조
- API 명세서 및 기능 설명
- 설치 및 실행 방법
- 팀 무한루프
- 1팀 : 손희정, 송치헌, 하예준
- 2팀 : (팀장)오지윤, 유동헌
이름 | 담당 기능 | 블로그 |
---|---|---|
공통 | 초기환경 설정, DB 모델링, UnitTest, 배포, swagger 문서 작성, README.md 작성 | X |
유동헌 | 게시글 카테고리, 검색, 대댓글 생성, 대댓글 조회(pagination), 조회수 | 1차 과제 TIL |
오지윤 | 게시글 카테고리, 검색, 대댓글 생성, 대댓글 조회(pagination), 조회수 | 1차 과제 TIL |
- 기능 별로 나누지 않고 모든 API를 함께 Pair Programming으로 구현하였습니다.
- README 작성
- 프로젝트 빌드, 자세한 실행 방법 명시
- 구현 방법과 이유에 대한 간략한 설명
- 완료된 시스템이 배포된 서버의 주소
Swagger
나Postman
을 통한 API 테스트할때 필요한 상세 방법- 해당 과제를 진행하면서 회고 내용 블로그 포스팅
Swagger
나Postman
을 이용하여 API 테스트 가능하도록 구현
- 에이모 선호 기술스택:
python flask
,mashmallow
,mongoengine
- 필수 사용 데이터베이스:
mongodb
✔️ REST API 기능
- 원티드 지원 과제 내용 포함(게시판 CRUD API)
- 게시글 카테고리
- 게시글 검색
- 대댓글 (1 depth)
- 대댓글 pagination
- 게시글 읽힘 수
- 같은 User가 게시글을 읽는 경우 count 수 증가하면 안 됨
- Rest API 설계
- Unit Test
- 1000만건 이상의 데이터를 넣고 성능테스트 진행 결과 필요
API URL: http://3.35.218.65:8000/
- Back-End:
Python 3.9.7
,Django 3.2.9
- Database:
mongodb
- Deploy:
AWS EC2
,Docker
- ETC:
Git
,Github
,Swagger
├── config
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── core
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── utils.py
│ └── views.py
├── postings
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── serializer.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── users
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── serializer.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── Dockerfile
├── my_settings.py
├── README.md
├── requirements.txt
[ 회원가입 API ]
- 유저 인증 처리를 위해 회원가입 API
- 유저의 이름과 이메일, 비밀번호를 요청 본문에 담으면 가입된다.
- Method: POST
"http://3.35.218.65:8000/users/signup"
- parameter : request_body
{
"name": "이광수",
"email": "runningman2@gmail.com",
"password": "12341234aA!"
}
- response
{
"message": "SUCCESS",
"username": "이광수"
}
[ 로그인 API ]
- 유저의 이메일과 비밀번호를 통해서 User Auth 검증 한다.
- 로그인 성공 시, 인가용 access_token을 반환한다.
- Method: POST
"http://3.35.218.65:8000/users/signin"
- parameter : request_body
{
"email": "runningman2@gmail.com",
"password": "12341234aA!"
}
- response
{
"message": "SUCCESS",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mn0.OLjKxY1ipx6vU8RSSkPtwE_d-0S9_qMVPg9syryaDQA",
"username": "이광수"
}
- 헤더로 user의 access_token을 전달한다.
- 요청 본문에 글 제목, 내용, 카테고리를 작성하여 요청한다.
- Method: POST
"http://3.35.218.65:8000/postings"
- header : Bearer token
- parameter : request_body
{
"title": "test_title",
"text": "test_content",
"category": 1
}
- response
{
"message": "test_title has successfully posted"
}
- 헤더로 user의 access_token을 전달한다.
- path_parameter에 해당하는 게시글이 조회된다.
- access_token으로 같은 유저가 게시글의 읽는 경우 조회수가 증가하지 않는다.
- Method: GET
"http://3.35.218.65:8000/postings/13"
-
header : Bearer token
-
parameter : path_parameter
-
response
{
"result": {
"id": 13,
"author": "이광수",
"title": "test_title",
"text": "test_content",
"category": "공지사항",
"created_at": "2021-12-23 07:30",
"updated_at": "2021-12-23 07:38",
"count": 4
}
}
- 기본적으로 10개의 게시글을 조회한다.
- Method: GET
"http://3.35.218.65:8000/postings/list"
- response
{
"result": {
"count": 10,
"postings": [
{
"id": 13,
"author": "이광수",
"title": "test_title",
"text": "test_content",
"category": "공지사항",
"created_at": "2021-12-23T07:30:52.607Z",
"updated_at": "2021-12-23T07:38:16.072Z"
},
{
"id": 12,
"author": "에이모1",
"title": "docker success",
"text": "good",
"category": "공지사항",
"created_at": "2021-12-22T06:37:32.229Z",
"updated_at": "2021-12-22T06:47:57.548Z"
},
...
{
"id": 3,
"author": "지석진",
"title": "testing post_2",
"text": "testing post text",
"category": "배송문의",
"created_at": "2021-11-02T09:02:04.461Z",
"updated_at": "2021-11-02T09:02:04.461Z"
}
]
}
}
- 헤더로 user의 access_token을 전달한다.
- 요청 본문에 제목, 수정할 내용, 카테고리를 전달한다.
- path_parameter에 해당하는 게시글의 내용이 수정된다.
- Method: PUT
"http://3.35.218.65:8000/postings/13"
- header : Bearer token
- parameter : request_body, path_parameter
{
"title": "test_title",
"text": "test_content_change",
"category": 1
}
- response
{
"result": {
"id": 13,
"author": "이광수",
"title": "test_title",
"text": "test_content_change",
"category": "공지사항",
"created_at": "2021-12-23 07:30",
"updated_at": "2021-12-23 07:47",
"count": 5
}
}
- 헤더로 user의 access_token을 전달한다.
- path_parameter에 해당하는 게시글이 삭제된다.
- Method: DELETE
"http://3.35.218.65:8000/postings/13"
-
header : Bearer token
-
parameter : path_parameter
-
response
{
"message": "test_title has successfully deleted"
}
- 헤더로 user의 access_token을 전달한다.
- path_parameter로 게시글 id를 전달한다.
- query_parameter인 comment_id가 없으면 댓글이 생성되고, 댓글의 id를 전달하면 해당 댓글에 대댓글이 생성된다.
- Method: POST
"http://3.35.218.65:8000/postings/12/comment?comment_id=41"
- header : Bearer token
- parameter : request_body, path_parameter, query_parameter
{
"content": "12번에 게시글 41번 댓글에 대한 대댓글입니다_1"
}
- response
{
"message": "CREATE_RECOMMENT"
}
- path_parameter로 조회할 게시글 id를 전달한다.
- query_parameter인 parent_comment_id가 없으면 해당 게시글의 댓글이 조회되고, 댓글 id를 전달하면 해당 댓글의 대댓글을 조회할 수 있다.
- query_parameter로 limit, offset를 전달하면 페이징 처리 후 조회된다.
- Method: GET
"http://3.35.218.65:8000/postings/12/commentlist?parent_comment_id=41&limit=10&offset=0"
-
parameter : path_parameter, query_parameter
-
response
{
"message": [
{
"content": "도커 짱",
"user": "runningman2@gmail.com",
"posting_title": "docker success",
"parent_comment_id": 41
},
{
"content": "도커 짱",
"user": "aimmo@naver.com",
"posting_title": "docker success",
"parent_comment_id": 41
},
{
"content": "댓글 댓글",
"user": "aimmo@naver.com",
"posting_title": "docker success",
"parent_comment_id": 41
}
]
}
- query_parameter로 검색할 키워드를 전달한다(키워드: post).
- 게시글 작성자, 제목, 내용으로 검색이 가능하다.
- Method: GET
"http://3.35.218.65:8000/postings/search?keyword=post"
-
parameter : query_parameter
-
response
{
"result": {
"count": 4,
"postings": [
{
"id": 3,
"author": "지석진",
"title": "testing post_2",
"text": "testing post text",
"category": "배송문의",
"created_at": "2021-11-02 09:02",
"updated_at": "2021-11-02 09:02"
},
{
"id": 4,
"author": "지석진",
"title": "testing post_4",
"text": "testing post text",
"category": "배송문의",
"created_at": "2021-11-02 09:06",
"updated_at": "2021-11-02 09:06"
},
{
"id": 5,
"author": "지석진",
"title": "testing post_5",
"text": "testing post text",
"category": "배송문의",
"created_at": "2021-11-02 09:06",
"updated_at": "2021-11-02 09:06"
},
{
"id": 6,
"author": "지석진",
"title": "testing post_6",
"text": "testing post text",
"category": "배송문의",
"created_at": "2021-11-02 09:06",
"updated_at": "2021-11-02 09:06"
}
]
}
}
- 해당 프로젝트를 clone하고, 프로젝트로 들어간다.
$ https://github.com/wanted-InfinityLoop/aimmo-InfinityLoop-2.git .
- 가상환경으로 miniconda를 설치한다. Go
$ conda create -n aimmo python=3.9
$ conda actvate aimmo
- 가상환경 생성 후, requirements.txt를 설치한다.
$ pip install -r requirements.txt
Django==3.2.9
django-cors-headers==3.10.0
bcrypt==3.2.0
PyJWT==2.3.0
djangorestframework==3.12.4
drf-yasg==1.20.0
djongo==1.3.6
whitenoise==5.3.0
gunicorn==20.1.0
django-extensions==3.1.5
- migrate 후 로컬 서버를 실행한다.
$ python manage.py migrate
$ python manage.py runserver
- 배포 서버에 접속하여 이미지를 pull 받는다.
$ sudo docker pull ojo1001/aimmo:0.1.0
- 이미지가 잘 받아졌는지 확인한다.
$ sudo docker images
- 컨테이너를 실행한다.
$ sudo docker run --name aimmo -d -p 8000:8000 ojo1001/aimmo:0.1.0
- 실행중인 컨테이너를 확인한다.
$ sudo docker ps
- Swagger API 문서로 들어가서 API를 테스트한다.
http://3.35.218.65:8000/swagger/