multiple API versions with common response model #5741
-
|
Hello! I'm currently using FastAPI to develop a web app with multiple "versions" that will be deployed simultaneously. I.e., I have both a So it's possible to have some common |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
|
you can create import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class FooRequest(BaseModel):
foo: str
class FooResponsev1(BaseModel):
foo: str
bar: str
class FooResponsev2(FooResponsev1):
baz: str
@app.post('/v1', response_model=FooResponsev1)
async def routerV1(request: FooRequest):
return FooResponsev1(foo=request.foo, bar=request.foo)
@app.post('/v2', response_model=FooResponsev2)
async def routerV2(request: FooRequest):
return FooResponsev2(foo=request.foo, bar=request.foo, baz=request.foo)
if __name__ == "__main__":
uvicorn.run("response_model:app", host="localhost", port=5000, workers=1, reload=True) |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for the response! Your suggestion was my first thought, but I was hoping for a slightly more "abstract" response model. Taking your example above: from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class FooRequest(BaseModel):
foo: str
class Bar(BaseModel):
pass
class FooResponse(List[Bar]):
pass
@app.post('/v1', response_model=FooResponse)
async def routerV1(request: FooRequest):
return FooResponsev1(foo=request.foo, bar=request.foo)
@app.post('/v2', response_model=FooResponse)
async def routerV2(request: FooRequest):
return FooResponsev2(foo=request.foo, bar=request.foo, baz=request.foo)and then in the # app/v1/schemas/bar.py
class BarV1(Bar):
xs: list[str]
# app/v2/schemas/bar.py
class BarV2(Bar):
xs2ys dict[str, float]The broad strokes differences between the
So I'm not sure if what I want can be done, and ultimately it's not the biggest thing in the world to just stick to option (1), but I figured I'd ask here to see if anyone had any ideas! |
Beta Was this translation helpful? Give feedback.
The whole point of having a v2 is usually to enable a different API without breaking existing clients.
Since for v1 you need to keep the existing schema and for v2 you want a different schema, using a shared schema is risky, because you might end up breaking v1 while changing for the new v2.
What you might want to consider is refactoring v1 implementation to an adaptor above v2 - translate the v1 schema to v2 schema and call the underlying v2 logic, then translating the v2 response back to v1. You could also use this technique to map from v2 to a non-FastAPI based model for your storage/business-logic and back, thus isolating your storage/business-logic model from your API model.