Faking a 404 with Refit
I'm interacting with a bunch of REST APIs using Refit, which is a really great C# library that allows you to write an annotated interface for an API and generates an implementation for it:
If everything works nicely you'll get back the API response nicely deserialized to an instance of
your object. If not, Refit will throw an ApiException
for you which will tell you what went
wrong, which we can catch and handle. Alternatively you can define the interface method with a
Task<ApiResponse<Thing>>
return type which wraps the deserialized object with the response
information and any error.
This works great, however I ran into a bit of a problem with one endpoint I'm interacting with,
which spuriously returns a 200 OK
status code for something that's not found, rather than a
404
. In this case, instead of sending the JSON object of the retrieved object, we get back
something like this:
As it happens this JSON will quite happily deserialize to an instance of Thing
, but getting a
blank object back is not what we want. Sending a 200
is obviously a bug in the endpoint which
I'm sure will get fixed eventually, however in the meantime I need to cope.
What to do?
Default Interface Methods to the rescue!
Instead of using the generated API method directly, we can hide the generated method by marking it
as internal
and then wrap it with a public method that does a bit of extra logic. In our case,
that extra logic will try to parse the response in a way that lets us check the status
property,
and if it's bad we can manually throw an ApiException
with a 404 Not Found
status, as if the
endpoint had done it itself:
Our new GetThing
implementation now behaves like you would expect, with 404 errors nicely faked
out. Well almost: we've disregarded the real response in the fake 404 exception, so we can't access
the returned content from the ApiException as we normally would, but in this case that's not a
concern as for a 404 the status code is probably all we really care about.