How does Retrofit work simultaneously with JSON and XML APIs?

Tram Ho

1. Set the problem

In Android projects that need to work with the API, we often use the Retrofit library. In addition to providing request API methods, Retrofit also provides an interface for working with serialization / deserialization libraries (such as Gson, Jackson, Moshi …) to support the conversion of API responses from text to form. object model in Java / Kotlin and vice versa for passing in request body.

However, for Retrofit to do this we need to provide it with a Converter Factory object. Retrofit provides a number of Converter Factory available to work with JSON and XML. But, in some cases we need to work with the response in both XML and JSON types? In this article I will give a way to help Retrofit can work with both types.

2. Converter Factory in Retrofit

To create a Retrofit object, we need to use the following syntax.

Ignoring the beards, pay attention to the addConverterFactory method. This method allows adding a new converter factory to Retrofit’s converter factory list. So why not add 2 converter factory like this?

It makes a lot of sense, but the problem is that when Retrofit creates a Converter it can only use one converter factory. Note Retrofit’s Converter.Factory class will see two methods below.

In case jsonConverterFactory.responseBodyConverter() returns null then it will use xmlConverterFactory.responseBodyConverter() . So if normal, only use the Retrofit Converter Factory first added.

Therefore, we will need to use a unique Converter Factory for Retrofit!

3. The idea of ​​an AutoTypeConverterFactory

The key issue is how to Convert Converter Factory recognize which API uses JSON, which API returns XML to return the corresponding Converter. It cannot wait for a response to return and then check, nor can it check the type of model response / request body because the number of models is very large. A better way is to use Annotation for the request methods of the API Service interface.

For JSON requests / response bodies, we will use the @JsonType annotation, while the XML type is @XmlType . Perhaps that is the most perfect way. We always know with each API, the type of transmission and return is the type.

The problem of determining the return / propagation type of the API has been completed. Now comes the section on How to Convert Factory automatically identify each type to return the appropriate converter.

Go back to the Converter.Factory class content with the two most important methods:

In the responseBodyConverter method, we have the parameter annnotations . The annotations parameter returns an array of annotations used with each method in the API Service. Now because we add annotations as @JsonType or @XmlType , they are also in this array. By checking the annotations parameter containing @JsonType or @XmlType we will determine which converter to use.

The requestBodyConverter method is similar, but the parameter to test will be parameterAnnotations because this is the parameter for the params passed in the request body.

By using 1 Converter Factory and checking the annotation, we will know when to use which converter and return the corresponding converter.

4. Embark on the code

I’ll give you an example with Kotlin. First, define two annotation classes:

Explained through:

  • @Target(AnnotationTarget.FUNCTION) : Annotation is only attached to a function / method.
  • @Retention(AnnotationRetention.RUNTIME) : Annotation takes effect during Runtime, does not affect Compile.

In the API Service interface just use this:

Now the main character: AutoTypeConverterFactory I will apply the State Design Pattern to this class so that it can switch back and forth between the two states “JSON state” and “XML state” so that the behavior also changes accordingly. You can apply many other ways such as using Delegate.

In each method, AutoTypeConverterFactory will always check for annotions -> update the current converter factory status -> call the corresponding converter factory’s current method. For example, when I use JSON Converter Factory as Gson , XML Converter Factory is TikXml , I can initialize AutoTypeConverterFactory as follows:

And insert it into Retrofit Builder like a regular converter factory:

That is done. Now Retrofit is ready to weigh two API types at a time.

5. Conclusion

Through this article, I have shared how to apply different types of response / request body in parallel and also explained relatively detailed about Converter Factory in Retrofit. If you have any suggestions or questions, please post them in the comments section.

Happy coding !!

Share the news now

Source : Viblo