DeanWay / fastapi-versioning

api versioning for fastapi web applications
MIT License
642 stars 63 forks source link

Docs showing routes of all versions #34

Open thetractor opened 3 years ago

thetractor commented 3 years ago

Hello,

I have a sample app with two versions of the user endpoint. Version 1 has an endpoint and version 2 has an other endpoint. Now if I navigate to the docs version 1 shows all correct but version two shows both of the endpoints together (the endpoint from v1 and the endpoint from v2)

Here my code:

# app/main.py
from fastapi import FastAPI
from fastapi_versioning import VersionedFastAPI

from app.v1.routers import users as users_v1
from app.v2.routers import users as users_v2

app = FastAPI()

app.include_router(users_v1.router)
app.include_router(users_v2.router)

app = VersionedFastAPI(app, version_format='{major}', prefix_format='/v{major}')
# app/v1/routers/users.py

from fastapi import APIRouter
from fastapi_versioning import versioned_api_route

router = APIRouter(route_class=versioned_api_route(1, 0))

@router.get("/users/v1", tags=["users"])
async def read_users():
    return [{"username": "Rick"}, {"username": "Morty"}]
# app/v2/routers/users.py

from fastapi import APIRouter
from fastapi_versioning import versioned_api_route

router = APIRouter(route_class=versioned_api_route(2, 0))

@router.get("/users/v2", tags=["users"])
async def read_users():
    return [{"username": "Rick"}, {"username": "Morty"}]

Here what I see in the docs when I navigate to http://localhost:8000/v2/docs image

I would expect the docs of version 2 to only show the endpoint defined in app/v2/routers/users.py and not a combination of both versions.

Thanx for any help with this!

crashCoder commented 2 years ago

Hello,

I believe this is not an issue, there is a bit of misunderstanding of how it works. Let me explain:

Basically what you are doing with this code router = APIRouter(route_class=versioned_api_route(1, 0)) is generating a new version, version 1 to be precise. The same happen with this one router = APIRouter(route_class=versioned_api_route(2, 0)), we create version 2.

The problem here is that you are specifying again version on the path e.g. "/users/v1" so this URL will look like this: http://localhost:8000/v1/users/v1

When you are adding the new route /users/v2, this is a completely different path as /users/v1 because remember, the versioning is already happening when we initialize APIRouter

When we create a new version all the routes from the past version will be replicated in the new version + the new routes with the new version

colibri17 commented 2 years ago

I am in the same situation. So there is no way to include in the new version all the routes of the new version + just the routes of the old version which are also referenced in the new one?

Up to now I ended up not to use fastapi_versioning at all, but creating separated APIRouter for the two versions.

peauc commented 2 years ago

@colibri17 To fix this I had to patch the library. In the file fastapi_versioning/versioning.py I moved the line 50 to line 53 and it works flawlessly