uplink icon indicating copy to clipboard operation
uplink copied to clipboard

Response Deserialization for Different Status Codes

Open mikeholler opened this issue 4 years ago • 2 comments

I'm trying to use the built in marshmallow support to handle deserialization for a login route. The service looks like this:

class AuthService(Consumer):
    @json
    @returns.json
    @post("oauth/token")
    def login_basic(
            self,
            body: Body(type=PasswordGrantTokenRequest.Schema)
    ) -> TokenGrantResponse.Schema:
        """Login using basic username/password credentials."""

The problem is when you get your username/password wrong, then you get a deserialization exception (because you get a 403 back instead of a 200, and the JSON payload is different). Retrofit solves this problem by supplying a Call as the top-level return, which then allows you to access the body and raw request, for status code checking. Is there a way for me to replicate this functionality easily within Uplink?

mikeholler avatar Dec 26 '19 15:12 mikeholler

@mikeholler, have you tried using a @response_handler?

@response_handler registers a callback to intercept responses before they are returned (or deserialized)

prkumar avatar Dec 26 '19 22:12 prkumar

@prkumar this is very helpful and certainly describes the presented use case. I'll definitely be able to use this for cases like that. This being said, the reason I mentioned Retrofit's call as a preference is access the response and the deserialized content. This may be a different question (feel free to consider it as such), but imagine a case where a header is sometimes returned along with a 200 JSON model that the client would like to read. Is there a way I can get the client access to lazy auto-deserialization via and the response headers? Or is that mutually exclusive?

mikeholler avatar Dec 26 '19 22:12 mikeholler