Use return type annotation for response_model by default. · Pull Request #875 · fastapi/fastapi

@ghost

This shouldn't be merged as-is, because I haven't added related tests yet, but I wanted to send this up for discussion. In my use case I am basically already returning the correct models from the endpoint functions already, and have return types enforced through mypy, so it feels quite unnecessary to duplicate the return type to the response_model argument to get the correct OpenAPI docs.

Basically I ended up creating a custom router that does similar logic as in this PR, but I am curious why it is not the default, since this behaviour would feel intuitive to me. I'm not offended at all if this gets rejected, but thought it's easier to explain what I'm asking through a PR instead of trying to explain it verbally in an issue.

@codecov

@tiangolo

Thanks for your interest @juhovh-aiven ! ✨

Check the note here in the "Technical Details": https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude

The response model is declared in this parameter instead of as a function return type annotation, because the path function may not actually return that response model but rather return a dict, database object or some other model, and then use the response_model to perform the field limiting and serialization.

It also means that if you return a dict but declare the return as a Pydantic model, mypy would rightfully complain, because you are not really returning the data type you declared your function to return.

It would be quite easy that in many cases the response_model doesn't really match the type of data that you are actually returning from your function, so it easily end up leading to confussion and mypy errors.

I'll close this PR, but feel free to add more comments, issues, or new PRs.

@ghost

Check the note here in the "Technical Details": https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude

Thanks for a quick response!

I had actually already checked that note in the "Technical Details", and I also use that feature quite heavily elsewhere (returning a dict and then validating/limiting fields through a pydantic model). However, my suggestion was simply about removing duplication, i.e. if the response_model and return annotation type are identical, one could skip the response_model part and simply go with the return annotation. If they are not identical one could still return a dict from the callable and simply set the response_model manually as before, the response_model value would always override whatever return annotation type is given.

But as mentioned, it's pretty easy to do with a custom route class with its own constructor, so I'll just keep going with that. Thank you for your good work with FastAPI, I must say I quite like it.

@ghost ghost deleted the default-response-model branch

January 17, 2020 13:07

@phy25 phy25 mentioned this pull request

Feb 2, 2020

@ghost ghost mentioned this pull request

Jun 4, 2020

@tiangolo