actix / actix/actix-web

Make it easier to consistently output JSON object from all endpoints

Offen
#1,604 7 Kommentare 15 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
A-web C-improvement
Vorherrschende Sprache
Rust
Sterne
24.8k
Forks
1.9k
Ø Merge
23 Std. 10 Min.
Gemergte PRs (30 T.)
26

Beschreibung

I think it's currently _possible_, but it should optimally be easier, and I don't know if I can make sure that all holes are covered.
The goal is that all endpoints _always_ output a JSON object (perhaps except in the case of 204 No Content).
Let's say that in the case of any error, we want
```
{
"code":
"message":
}
```
The first thing I tried to this end was to simple create one single middleware that should cover all cases: https://gist.github.com/Ploppz/54e65eea580f17764c7560a3e7190141
This one simply checks if the status code of a response is not success, then it puts the whole body into the "message" field of the above JSON structure. This mostly works because
1) actix-web simply returns the error as string
2) we impl ResponseError like this
```rust
impl ResponseError for MyError {
fn error_response(&self) -> HttpResponse {
use Error::*;
let status = match self {
//omitted code
};
HttpResponse::with_body(status, Body::from(&self.to_string()))
}
}
```

However, in some cases I found it desirable to return a status like 404 or 503 while also already returning JSON in the request handler. This does not work well in this solution, because it will put the JSON into the "message" field of the above JSON structure.
This solution assumes that when a request handler returns `Result`, T always means JSON with 2xx HTTP code and E always means an error that is only string.

So I think this is the way to go to cover most cases right now:
* `impl ResponseError for MyError` where we return Result<_, MyError> from all endpoints; this implementation will serialize said JSON format with `self.to_string()` in the `"message"` json field.
* Use [JsonConfig](https://docs.rs/actix-web/3.0.0-alpha.3/actix_web/web/struct.JsonConfig.html) to cover most actix-generated 400 errors.
* Iirc there's something to set custom 404 response

It took me a lot of effort to just get to this point to make a consistent API, and I'm not even sure if it will always work well - I don't know all possible cases in which actix-web can throw an error before invoking a request handler.

I wish there was a way to tell actix-web to transform absolutely all error responses in the same way, rather than e.g. only configuring the Json extraction error handling.

Otherwise, is it possible to adapt the ErrorHandler middleware I provided to _only_ transform errors that stem from actix-web? As far as I can see, it's not possible to see whether an error is generated by a request handler or by actix-web in a middleware.

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.