안녕하세요. 이번 시간에는 fastapi에서 path parameter를 활용하는 방법을 알아봅시다. 그리고 조심해야 할 점도 같이 알아보겠습니다.

 


 crud 정도는 많이 익숙하실 겁니다. 예를 들어, 게시판에서 글을 쓰는 행동을 생각해 봅시다. 우리가 글을 쓰면 어딘가에 글에 대한 데이터가 저장될 거에요. 이 글을 '자원'이라고 하겠습니다. 글들이 여러 개 있을 때, 그 중 하나를 특정지을 수 있을 겁니다. 즉, 특정한 자원에 접근하는 방법을 알려주기 위해 path parameter를 쓴다고 생각하시면 되겠습니다.

 

 주소를 봅시다. /users/{user_id}가 있습니다. user들이라는 자원이 있습니다. 특정한 유저에는 어떻게 접근을 해야 할까요? 고유 id값을 주면 됩니다. 고로 저는 GET /users/{user_id}를 만들었습니다. 이 user_id를 받습니다. 그렇게 한 다음에 id가 user_id인 유저에 대한 정보를 돌려주는 api라고 생각하면 됩니다.

 

 그런데, regex가 있습니다. 숫자로만 이루어 져야 한다는 전제가 붙어있네요. Path(regex="^[0-9]+")는 user_id에 길이 1이상, 숫자로만 이루어진 문자열을 받습니다.

 

 GET /users/3을 호출해 봅시다. 그랬더니 3번 유저에 대한 정상적인 정보가 출력됩니다.

 

 

 그런데, a3을 넘기니 그렇지 않네요. regex 패턴에 맞지 않기 때문입니다. 여기까지만 보면 뭔가 단순해 보입니다. query랑 크게 다를 바가 없어 보이고, 실제로도 사용법이 비슷합니다. 그런데, 조심해야 할 점이 있습니다.

 


 문제 상황을 보겠습니다.

 

 GET /users/{user_id} 하고, GET /users/me가 있습니다. 이제 GET /users/me를 호출해 봅시다. 그러면 get_users_me가 제대로 동작할까요?

 

 

 422가 떨어집니다. 왜 그럴까요? 이는 /users/me가 /users/{user_id}에도 걸리기 때문입니다. "me"라는 것을 {user_id}가 받아먹을 수도 있기 때문입니다. 이를 도식화 해서 나타내면 아래와 같습니다.

 

 평가 순서가 요래 되는데요. /users/me가 /users/{user_id}에 걸리기 때문에 해당 api를 호출하기 위해 부르는 path parameter의 validation logic에 들어가게 됩니다. me는 숫자로만 이루어진 문자열이 아니기 때문에 거부당합니다. order 순서를 바꿔 보겠습니다.

 

 요래 바꿔보겠습니다. 그리고 나서 다시 /users/me를 호출해 보겠습니다.

 

 그랬더니 이번에는 get_users_me가 제대로 호출되었음을 확인할 수 있습니다. 이를 도식화 시키면 아래와 같습니다.

 

 order가 GET /users/me부터 되었기 때문에, 이 경우 먼저 평가되게 됩니다. , GET /users/{user_id}가 평가되기 전에 GET /users/me가 먼저 평가되기에 아까와는 다르게 정상적으로 수행됩니다.

 

 

 이건 어떨까요? 딱 봐도 /users/me는 아니여 보입니다. 쉽게 말하면 이 api는 GET /users/me가 될 수 없습니다. 3과 me는 다르기 때문입니다.

 

 

 따라서 2번째 order인 /users/{user_id}가 평가되게 됩니다. ordering 순서만 바꾸었을 뿐인데, 내 정보를 출력하는 것과 남의 정보를 출력하는 것이 정확하게 되었습니다. 여기서 더 중요한 것은, 이 때 user_id는 절대로 me가 나오면 안 된다는 것입니다. 만약에 그렇게 된다면, "me"라는 id를 가진 유저를 조회해 주세요. 라는 요청이 들어왔을 때, 뜬금없이 내 정보를 조회할 수 있기 때문입니다.

 

 이 점 유념하고 api를 설계하고 ordering을 하는 것이 좋습니다.