2. 경로 매개변수
HTTP 파이
HTTP 요청을 생성하고 응답을 볼 수 있는 도구들을 다음과 같이 다양하다.
- curl - terminal에서 사용
- wget - terminal에서 사용
- Postman 또는 Insomnia - UI 프로그램
- HTTPPie
(fastapi) PS D:\workspace\fastapi> pip install httpie
FastAPI 앱을 실행하고, 다음을 실행하면 응답을 받을수 있다. 호스트가 localhost인 경우 호스트를 생략할 수 있다.
경로 매개변수 (path parameter)
경로 매개변수(Path Parameters)는 흔히 우리가 말하는 URL 경로에 들어가는 변수를 의미한다.
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get('/users/{user_id}')
def get_user(user_id):
return {'user_id': user_id}
if __name__ == '__main__':
uvicorn.run('main:app', reload=True)
이제 http://localhost:8000/users/123 을 호출하면,
(fastapi) PS D:\workspace> http :8000/users/123
HTTP/1.1 200 OK
content-length: 17
content-type: application/json
date: Sat, 13 Aug 2022 08:20:33 GMT
server: uvicorn
{
"user_id": "123"
}
문자열 123을 응답으로 받았다. 이처럼 http 통신은 타입 없이 전부 문자열로만 통신한다. 이 때 정수형 123을 응답으로 받고 싶으면 어떻게 해야 할까? 아래와 같이 타입 힌트를 추가해 주면 된다.
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get('/users/{user_id}')
def get_user(user_id: int):
return {'user_id': user_id}
if __name__ == '__main__':
uvicorn.run('main:app', reload=True)
(fastapi) PS D:\workspace> http :8000/users/123
HTTP/1.1 200 OK
content-length: 15
content-type: application/json
date: Sat, 13 Aug 2022 08:23:35 GMT
server: uvicorn
{
"user_id": 123
}
만약에 누가봐도 정수형이 아닌 user_id를 넘겨주었을 때는 어떻게 되는지 확인해보자.
(fastapi) PS D:\workspace> http :8000/users/dijlgijlkdjfw
HTTP/1.1 422 Unprocessable Entity
content-length: 104
content-type: application/json
date: Sat, 13 Aug 2022 08:25:15 GMT
server: uvicorn
{
"detail": [
{
"loc": [
"path",
"user_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
이렇게 어떤 부분이 오류인지 까지 알려주고 자동으로 에러 핸들링을 해준다.
swagger에서도 동일하게 확인해 볼 수 있다.
FastAPI 주의점 (순서 문제)
이번에는 현재 유저를 반환하는 앤드포인트를 추가해보겟다.
import uvicorn
from fastapi import FastAPI
app = FastAPI() # fastapi app 인스턴스화
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}
# 추가: 현재 유저를 반환하는 앤드포인트
@app.get("/users/me")
def get_current_user():
return {"user_id": 123}
if __name__ == '__main__':
uvicorn.run('main:app', reload=True)
이제 요청을 보내보자.
(fastapi) PS D:\workspace> http :8000/users/me
HTTP/1.1 422 Unprocessable Entity
content-length: 104
content-type: application/json
date: Sat, 13 Aug 2022 08:32:49 GMT
server: uvicorn
{
"detail": [
{
"loc": [
"path",
"user_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
에러가 난다. 그 이유는 me 라는 user_id 가 들어 왓을 때 fastAPI는 코드 상에 위에서 아래로 실행하기 때문에 get_user(user_id: int)로 먼저 들어가 타입 에러를 내뱉기 때문이다. 이는 코드의 순서를 바꾸기만 하면 해결된다.
import uvicorn
from fastapi import FastAPI
app = FastAPI()
# 추가: 현재 유저를 반환하는 앤드포인트
@app.get("/users/me")
def get_current_user():
return {"user_id": 123}
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}
if __name__ == '__main__':
uvicorn.run('main:app', reload=True)
(fastapi) PS D:\workspace> http :8000/users/me
HTTP/1.1 200 OK
content-length: 15
content-type: application/json
date: Sat, 13 Aug 2022 08:34:43 GMT
server: uvicorn
{
"user_id": 123
}
(참고) curl 명령어
curl 명령어 예시
$ curl [options] [URL...]
이 명령은 터미널 창에 example.com 홈페이지의 소스 코드를 인쇄한다.
$ curl example.com
- -X: –request
Specify request command to use - -H: –header HTTP Header에 에 추가. 위 예제에서는 Content-Type:application/json 과 Authorization: Bearer abcdbdg을 추가함
- -d: –data HTTP POST data
- –data-ascii HTTP POST ASCII data
- –data-binary HTTP POST binary data
$ curl -X POST\
-H Content-Type:application/json\
-H Authorization: Bearer abcdbdg\
-d @data.json\