목업 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 작성

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에서 흉내를 내려면 이정도가 최선이 아닐까 싶다.

profile
FE개발자 가보자고🥳

1개의 댓글

comment-user-thumbnail
2024년 4월 22일

버전이 궁금하네요.
최근에 다시 써볼 일이 있어 꺼냈다가 2depth 호출 ( users/:userId/folders 등등) 이 아예 안되는 걸 보고, 당황하고 있네요.

답글 달기

관련 채용 정보