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

[question] Example of code registering middleware for a specific routes #587

Closed
theruziev opened this issue Jul 25, 2019 · 2 comments
Closed

Comments

@theruziev
Copy link

Can anybody show example of registering middleware for a specific routes or mounts?

Thanks

@theruziev
Copy link
Author

I found the answer myself. You can register middleware for a route by wrapping route's app with middleware like this:

from starlette.applications import Starlette
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import JSONResponse
import uvicorn
from starlette.routing import Router, Route

app = Starlette(debug=True)


class CustomMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        response = await call_next(request)
        response.headers['Custom-Header'] = 'Example'
        return response


async def homepage(request):
    return JSONResponse({'hello': 'world'})


async def me(request):
    return JSONResponse({'user': 'its me'})


home_route = Route("/", homepage)
home_route.app = CustomMiddleware(home_route.app)

app.mount("/", Router([
    home_route,
    Route("/me", me)
]))

if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)

@tomchristie what are you thinking about adding method for registering middleware for Router, Route, Mount?
My use case is registering rate limiter or RequestID for specific groups of endpoints.
If it's a good idea, I can add a PR for registering middleware for specific routers.

@mreschke
Copy link

mreschke commented Feb 3, 2021

Route specific middleware has always been a requirement for my projects, both web and api based. Before moving to Python I worked with PHP Laravel for years and their idea of Global, API, Web and Route specific middleware was extremely beneficial. I will be attempting this in Starlette myself, but it would be ideal if starlette could provide this out of the box.

routes = [
    Route("/", endpoint=homepage, middleware=[abc, xyz]),
]

Or in you class based endpoints

class Homepage(HTTPEndpoint):
   middleware = [abc, xyz]

    async def get(self, request):
        return PlainTextResponse(f"Hello, world!")

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

No branches or pull requests

2 participants