Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow empty routed path (issue #414) #415

Merged
merged 1 commit into from Aug 25, 2019
Merged

Allow empty routed path (issue #414) #415

merged 1 commit into from Aug 25, 2019

Conversation

vitalik
Copy link
Contributor

@vitalik vitalik commented Aug 1, 2019

With this patch it should be possible now to include empty route path
it also checks if both path and prefix are not empty
see #414 for more details

@vitalik
Copy link
Contributor Author

vitalik commented Aug 2, 2019

hi

do you think this will land to release ? (we are just trying to understand our project strategy... )

@pablogamboa
Copy link
Contributor

This feature also interests me quite a lot! Perhaps not this exact implementation, but I think it would be very beneficial to have the flexibility of having routes without a trailing slash 👍

@euri10
Copy link
Contributor

euri10 commented Aug 8, 2019 via email

@pablogamboa
Copy link
Contributor

yeah you're right @euri10 the discussion should be moved there

@vitalik
Copy link
Contributor Author

vitalik commented Aug 8, 2019

I don't like the idea of having FastAPI behaving differently than Starlette, if this should land it should be upstream imho, or not at all. Le jeu. 8 août 2019 à 8:03 AM, Pablo Marti
Hi @euri10 , @pablogamboa

Well you forgetting that Starlette's endpoints can handle multiple http methods (GET, POST, HEAD, PUT) with one function, while what nice about fastapi - each method handled in separate function...

So I would not inherit ALOT Starlette's' approach (well I actually question them for not allowing ending slashes as well)

Just take a look at this example API structure:

GET  /cats
POST /cats
GET  /cats/{id}/children
POST /cats/{id}/children
GET  /cats/{id}/tasks
POST /cats/{id}/tasks
GET  /cats/{id}/activities
POST /cats/{id}/activities
GET  /cats/{id}/food
POST /cats/{id}/food
GET  /dogs
POST /dogs
GET  /dogs/{id}/children
POST /dogs/{id}/children
GET  /dogs/{id}/tasks
POST /dogs/{id}/tasks
GET  /dogs/{id}/activities
POST /dogs/{id}/activities
GET  /dogs/{id}/food
POST /dogs/{id}/food
GET  /birds
POST /birds
GET  /birds/{id}/children
POST /birds/{id}/children
GET  /birds/{id}/tasks
POST /birds/{id}/tasks
GET  /birds/{id}/activities
POST /birds/{id}/activities
GET  /birds/{id}/food
POST /birds/{id}/food

if fastapi allowed me to to use empty route - it would lead just 3 lines of code:

app.include_route(..., prefix='/cats')
app.include_route(..., prefix='/dogs')
app.include_route(..., prefix='/birds')

without empty path in route I will have to do the following:

app.get('/cats', cats_get)
app.post('/cats', cats_post)
app.include_route(..., prefix='/cats')

app.get('/dogs', dogs_get)
app.post('/dogs', dogs_post)
app.include_route(..., prefix='/dogs')

app.get('/birds', birds_get)
app.post('/birds', birds_post)
app.include_route(..., prefix='/birds')

not only it produces 3 times more code, but also my views will have weird functions cats_get, cats_post without decorators

how else I would make it nicer ?

@euri10
Copy link
Contributor

euri10 commented Aug 8, 2019 via email

@vitalik
Copy link
Contributor Author

vitalik commented Aug 8, 2019

@euri10 well - it does not work - try it...

you cannot include these endpoints without ending slash

GET  /cats
POST /cats

but making it outside routed views makes code less modular/incapsulated

@euri10
Copy link
Contributor

euri10 commented Aug 8, 2019 via email

@steinitzu
Copy link
Contributor

Redirects don't solve this for me. I want my route to be documented as GET /cats not GET /cats/ as it's consistent with my other endpoints that don't have a trailing slash.

What's the reason for not allowing empty paths?

@dmontagu
Copy link
Collaborator

@steinitzu I'm assuming it's just a way to ensure you don't accidentally end up with paths that aren't separated by slashes. Either way, to @euri10's point, I think that the right place to ask this question would probably be on starlette because of this: https://github.com/encode/starlette/blob/master/starlette/routing.py#L147

@vitalik
Copy link
Contributor Author

vitalik commented Aug 16, 2019

@dmontagu well starlette routing have nothing to do with fast-API app.get/post/patch.. these a re different code basses

I'm assuming it's just a way to ensure you don't accidentally end up with paths that aren't separated by slashes

my pull request is actually makes this check - if you use empty routed path and include - it will throw an error

@dmontagu
Copy link
Collaborator

@vitalik

well starlette routing have nothing to do with fast-API app.get/post/patch

I think that's a little extreme; clearly they are related -- APIRoute is a subclass of starlette.routing.Route after all.

That said, it is a valid point that include_router doesn't exist in starlette, so this concern wouldn't apply. Given APIRoute is typically added to an app via include_router I'm convinced this is a reasonable change. I personally would be fine with merging it.

Either way, it would certainly be less controversial if there was a way to implement this that didn't remove validation that would be typically be performed in the superclass.

@vitalik
Copy link
Contributor Author

vitalik commented Aug 16, 2019

I'm sorry - maybe I am extreme , sorry about that - but this patch is only removing one line with assert inside fastapi code (have nothing to do with starlette) that's it (plus extra check that both include an route are not empty)

if you can give me any other option how to make my code more modular/isolated withot this assert - I would be happy to use it

@vitalik
Copy link
Contributor Author

vitalik commented Aug 23, 2019

Hi @tiangolo
Can you share your concerns or plans about this PR ?

Thank you

@tiangolo tiangolo merged commit f7f17fc into tiangolo:master Aug 25, 2019
@tiangolo
Copy link
Owner

Thank you @vitalik ! Merged! 🎉 🚀


I think I can agree with you all 😄

I agree I don't want to diverge from Starlette, but it's true that the router functionality and the "path operations" are already handled differently.

I think for a new developer to find a path operation with an empty route in an existing codebase could be confusing, and that in some cases it could be more "intuitive" to have paths that are a prefix of other paths always have a trailing slash.

But that's a bit subjective, depending on the point of view, in fact, GitHub itself has by default the contrary behavior, the one that would be supported by this feature (it's https://github.com/tiangolo/fastapi , not https://github.com/tiangolo/fastapi/).

I also see that this is a feature that seems to help several use cases (at least 3, just from this thread), and I think it might help especially with some migrations, to keep paths consistent with previous implementations. Also, the flexibility it adds doesn't break current behavior, so I think it's fine.

Thanks for your contribution @vitalik ! And thanks for the interest and discussion here everyone!


Now, although I ran the tests locally first (and they passed), as Travis seems to have not triggered, I see now there's a mypy error after merging 😞. So I'll fix it before a release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants