abersheeran / asgi-ratelimit

A ASGI Middleware to rate limit
Apache License 2.0
292 stars 11 forks source link

Update readme with JSON response for custom block handler #21

Closed mlexs closed 3 years ago

abersheeran commented 3 years ago

Can you describe in detail why you want to add this sample?

mlexs commented 3 years ago

All our API endpoints return data in JSON format, including cases where API returns erros due to user input being invalid etc. Except the 429 handler that returned bytes (by default).

It took me a little while to figure out the ASGI way to do so and I thought I could share this with others. That's it.

abersheeran commented 3 years ago

I don't really want ASGI-ratelimit and ASGI framework to bind. In addition to Starlette, we also support Quart, blacksheep, Index.py and other ASGI frameworks. Excessive use of a certain framework in the README (already supports the Starlette session) may cause misunderstandings "asgi-ratelimit is written for xxx" of". but it is not the truth.

If you just share how to use it, you can send it to discussions. By the way, you can use JSONResponse directly.

RateLimitMiddleware(..., on_blocked=JSONResponse({"message": "Too Many Requests"}))
mlexs commented 3 years ago

No worries.

euri10 commented 3 years ago

in fact JSONResponse from Starlette is an asgi application itself @ahasoftware, and that asgi application just sets the headers for you, if you look at the code it inherits Response which implements this __call__

    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
        await send(
            {
                "type": "http.response.start",
                "status": self.status_code,
                "headers": self.raw_headers,
            }
        )
        await send({"type": "http.response.body", "body": self.body})

        if self.background is not None:
            await self.background()
mlexs commented 3 years ago

Yeah maybe maybe. The status code defaults to 200 but not an issue any more as I've got it covered and it's working.

FYI also prefer to have the custom blocked method defined as it's in my example as it doesn't obscure RateLimitMiddleware so much. also I check for some info in request data but this was left out of the example for simplicity's sake.