You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[I've keyword-stuffed the title so that even if you decide not to do this some poor soul in the same situation has a better chance of finding this solution. I've searched through this repo's issues and PRs and couldn't find anything else discussing this]
This works exactly as you would expect on receiving JSON, ... "context": "home" ... deserializes to FilterContext.HOME correctly.
Naively you might expect that if Moshi's converter factory is correctly added to Retrofit then calling through to an API defined like this:
@FormUrlEncoded
@POST("api/v2/filters")
suspendfuncreateFilter(
@Field("title") title:String,
@Field("context[]") context:List<FilterContext>, // <-- FilterContext used here
@Field("filter_action") filterAction:String,
@Field("expires_in") expiresInSeconds:Int?,
): NetworkResult<Filter>
would cause Retrofit to also use the @Jsonname property to serialise the FilterContext.
But of course it doesn't, because @FormUrlEncoded is not JSON, so the enum values are sent as uppercase and rejected by the server.
Since I'm loathe to repeat an identical lowercase string representation of the enum I wrote this and added it as an additional converter factory when creating the Retrofit singleton in my app.
It's a singleton converter and converterfactory that uses the value of the @Json(name = ...) property if it exists on the enum, falling back to the normal string representation if it doesn't.
[Creating a Moshi adapter for the type and calling toJson on the adapter doesn't work for this use case because then the enum value is wrapped in quotes -- correct for JSON, not correct here]
Would the Moshi team be interested in bundling this with Moshi? Either:
As a separate converter factory, mentioned in the docs?
As an option (default off) to the existing converter factory?
Mentioning this as an example of how Moshi's annotations can be used in adjacent contexts?
Absolutely no problem if not; at the very least I hope this writeup is useful to anyone else who encounters a similar issue.
The text was updated successfully, but these errors were encountered:
I would say that as-written this is fairly specific. It works for enums, but not classes. It also doesn't honor any JsonAdapters one might be using for enums installed in a Moshi instance.
I'm not sure there's a perfect solution here that I would feel comfortable shipping in an artifact. I'd be happy to accept something like what you wrote to Retrofit's samples, though.
[I've keyword-stuffed the title so that even if you decide not to do this some poor soul in the same situation has a better chance of finding this solution. I've searched through this repo's issues and PRs and couldn't find anything else discussing this]
I'm working with an API that sends JSON in response to requests, but sometimes expects updates to be POSTed with form URL encoding (https://docs.joinmastodon.org/methods/filters/).
There's an interesting wrinkle with this that I've just become aware of. Using that API as an example I have an enum to represent filter contexts:
This works exactly as you would expect on receiving JSON,
... "context": "home" ...
deserializes toFilterContext.HOME
correctly.Naively you might expect that if Moshi's converter factory is correctly added to Retrofit then calling through to an API defined like this:
would cause Retrofit to also use the
@Json
name
property to serialise theFilterContext
.But of course it doesn't, because
@FormUrlEncoded
is not JSON, so the enum values are sent as uppercase and rejected by the server.Since I'm loathe to repeat an identical lowercase string representation of the enum I wrote this and added it as an additional converter factory when creating the Retrofit singleton in my app.
It's a singleton converter and converterfactory that uses the value of the
@Json(name = ...)
property if it exists on the enum, falling back to the normal string representation if it doesn't.[Creating a Moshi adapter for the type and calling
toJson
on the adapter doesn't work for this use case because then the enum value is wrapped in quotes -- correct for JSON, not correct here]Would the Moshi team be interested in bundling this with Moshi? Either:
Absolutely no problem if not; at the very least I hope this writeup is useful to anyone else who encounters a similar issue.
The text was updated successfully, but these errors were encountered: