Actually, they are completely different.
Let's take the URL of questions tagged with FastAPI link as an example and split into parts.
https://stackoverflow.com/questions/tagged/fastapi?sort=Newest&uqlId=26120
- stackoverflow.com -> domain
- /questions -> Path
- /tagged -> Path
- /fastapi -> Path param.
- sort=Newest -> Query Param.
- uqlId=26120 -> Query Param.
If you wanted to create this in FastAPI it would look something like this.
from enum import Enum
class SortTypes(str, Enum):
newest: str = "Newest"
unanswered: str = "Unanswered"
active: str = "Active"
bountied: str = "Bountied"
@app.get("/questions/tagged/{tag}")
async def get_questions_with_tags(tag: str, sort: SortTypes, uqlId: int):
return ...
Query params and path params work nearly the same.
But the body is completely different.
You can not see the body of the Request from URL, your client sent HTTP Body as bytes but it can contain anything, and you need to specify what body contains via HTTP Headers.
By doing that, you are telling the server how it should handle that body. For example
Imagine you are sending a JSON {"name": "foo"}
and it will be sent with this header {"Content-Type": "application/json"}
, your client handles this because by default FastAPI returns JSONResponse
,there are also other response types like StreamingResponse
, FileResponse
, HTMLResponse
etc (You can read common Content-Type's from here).
The main difference between Query params and the Path params is they are accessible from URL and they are strings. But Body is but and usually, it carries data.
Imagine you have a kinda bigger application and you are using Query
params for all your communication between the client and the server. It will be a complete disaster.
For example, now you are reading this answer right? But how did it came? All the details your id, your reputation, the question itself comes as body. Imagine sending all this inside the URL, total disaster.
For further reading, you can check these answers to see Best Practices for designing a REST API.