목업 API를 만들다가 삽질해서 기록하는 포스팅.
데모로 폴더가 존재하는 투두 리스트 서비스를 만들고 있었고, 다음과 같은 JSON을 만들었다.
JSON Server의 db.json
{ "users": [ { "id": "sangpok", "nickname": "상폭", "folders": [ { "id": "folderIdA", "name": "폴더A", "todos": [ { "id": "todoIdA", "content": "할일A", "completed": false } ] } ] } ] }
그리고 다음과 같은 EndPoint가 있었다.
Todo API
- /users
- /users/:userId
- /users/:userId/folders
- /users/:userId/folders/:folderId
- /users/:userId/folders/:folderId/todos
- /users/:userId/folders/:folderId/todos/:todoId
그러나,, json-server에서는 저렇게 ~/folders를 지원하지 않는다고 한다. 뭐라고!
방법이 없는 건 아니고,, Custom Routes을 써야 한다고 한다.
Custom Routes를 작성하기 전에, 먼저 알아두어야 할 것은 json-server는 1depth만 지원한다는 점이다. 이게 뭔소리냐면,, 다음와 같은 db.json이 있다고 해보자.
{ "users": [ { "id": "sangpok", "nickname": "상폭", "folders": [ ~ ] } ] }```
sangpok의 folders에 접근하기 위해 endpoint로 /users/sangpok/folders
로 접근하면 1depth만 지원하기 때문에 해당 요청은 무시된다. (/users/sangpok
까지만 지원)
이에 대해서 개발진들은 1depth 주소에 folders를 만들고, custom routes로 /users/sangpok/folders
로 접근하면 /folders
의 데이터가 나오게끔 설정해주는 방법을 제시했다.
routes.json
왼쪽(Key)의 경로가 들어오면 오른쪽(Value)의 경로로 가라.
{ "/users/:userId/folders": "/folders" }
db.json
{ "users": [ { "id": "sangpok", "nickname": "상폭", } ], "folders": [ { "id": "folderIdA", "name": "폴더A", "todos": [ ~ ] } ] }```
마찬가지로 /folders/todos
에 접근하려면 1depth에 새로 만들어주고 라우팅해줘야 한다.
routes.json
{ "/users/:userId/folders": "/folders", "/users/:userId/folders/:folderId/todos": "/todos", }
db.json
{ "users": [ { "id": "sangpok", "nickname": "상폭", } ], "folders": [ { "id": "folderIdA", "name": "폴더A", } ], "todos": [ { "id": "todoIdA", "content": "할일A", "completed": false } ] }```
하지만 내가 원하는 건 각 계정마다의 투두 폴더, 각 투두 폴더 마다의 투두 목록이었다. 저런 식으로 만들면 /users/sangpok/folders
으로 접근하든, /users/juhen/folders
로 접근하든 같은 값이 나올 것이다. 다른 값이 나와야지! 삽질의 시작
여러 방법을 시도해봤는데,, 이 방법이 제일 깔끔해서 공유해본다. 다른 방법이 있다면 제발 알려주십쇼...
filter 연산자 이용하기
- 각 1depth의 값마다 부모의 id를 넣어서 filter 연산자를 이용하는 것이다. folders의 값들엔 userId가 들어가고, todos의 값들엔 userId와 folderId가 들어가게 만든 다음, filter 연산자를 이용해 해당 값들만 출력하게 만드는 방식.
routes.json
{ "/users/:userId": "/users/:userId", "/users/:userId/folders": "/folders?userId=:userId", "/users/:userId/folders/:folderId": "/folders/:folderId", "/users/:userId/folders/:folderId/todos": "/todos?userId=:userId&folderId=:folderId", "/users/:userId/folders/:folderId/todos/:todoId": "/todos/:todoId" }
db.json
{ "users": [ { "id": "sangpok", "nickname": "상폭", } ], "folders": [ { "id": "folderIdA", "userId": "sangpok", "name": "폴더A", }, ], "todos": [ { "id": "todoIdA", "userId": "sangpok", "folderId": "folderIdA", "content": "할일A", "completed": false } ] }
모양새가 조금 꼴사납지만,, 관계형 DB가 아닌 JSON Server에서 흉내를 내려면 이정도가 최선이 아닐까 싶다.
버전이 궁금하네요.
최근에 다시 써볼 일이 있어 꺼냈다가 2depth 호출 ( users/:userId/folders 등등) 이 아예 안되는 걸 보고, 당황하고 있네요.