I have a REST API which returns JSON to its calls. However, depending on the call I perform, the answer varies. Using Gson will result in a different POJO object for each API response.
Considering I have an IntentService who handles all my GET requests, and I only pass it an URL in the intent, what would be the best way to handle the different responses in the IntentService?
I've been messing around with JSONs in Android for a while, but I can't seem to find an elegant/smart solution for this issue. I've been creating an enum to differentiate the possible API requests, and passing the selected enum value in the intent, in order for the IntentService to choose the action to perform using a switch statement.
Thank you.
If there is a common business logic for all the resulting different POJOs you get, then it would be nice to try to use the same Class, and for this, to try to customize the GSON mapping strategy.
If you don't really have a common logic, then you can consider your GSON objects as DTOs, and then your "mapping" to the business Classes is done on a lower layer (And you have here a lot of ways to do it, including Dozer).
For a more specific answer, more details or examples for your project would help.
Related
Hello Dear Developers,
I am working on a project which uses Flickr API, I parsed the data and took the necessary values from JSONArray and JSONObject, however the URL does not provide all the necessary information about the user (the user who shared the photo on Flickr ) for this reason I decided to use flickr.people.getInfo but in this situation, how can I handle response JSON, I mean if I parse this URL, I have to change RecyclerView Adapter, ViewHolder, but it is not sufficient way of handling multiple different API calls.
I hope, the explanation is clear, if it is not pleasing make comment then I will provide answers to your specific questions.
If I understood correctly you should make two calls, then merge responses together and show result into UI.
You can handle this with callbacks or RxJava observables.
The main idea is to create a single class - model that will contain all data you need to present on your UI. Then make the first network call and parse the response into this object. Pass this object to the next network call and update it with the corresponding user data. And only after these two calls are done and you collected all needed data you can insert the model into RecyclerView.
Hope it helps.
I've just started learning about Retrofit 2. I need to consume a RESTful API for an existing Android app. Essentially, the data model for the Android app already exists. I have a REST service which doesn't directly translate to the model classes / properties used by the app (i.e. internally the class properties do not comply with the kind of naming required by Retrofit to work automatically).
For example, given a Car object, the API may return make, model and color. The app's internal model has an existing Vehicle class instead, and property names do not directly map. Moreover, there are certain properties that must be initialized in a particular order.
I know this qualifies for a Custom Converter but would you suggest I instead look into a custom Gson Deserializer? Would that be a better / easier choice instead?
Any guidance would be appreciated as I've just started reading up on Retrofit. I like the fact that I don't have to write all the boilerplate code, yet I feel like I'm unable to utilize its full potential given I need to 'map' all the objects and their properties manually.
There are several things you need to consider:
1) Does you API response keeps the same (even with missing attributes) format
then:
1.1) you can make a custom converter or deserializer
1.2) modify&sync your internal Android model to represent the one you receive or vice versa as if your Android model differ allot it can involve lots of computation on every response
else:
2)if your API responses are in different format and it is really RESTful API then you should have information of the media type by some means in the header or in the body of the response and based on this info you can then choose the appropriate converter/deserializer.
This is more like Custom Converter that delegates to another Converter based on the actual response.
For both scenarios you can apply some kind of in-the-middle converter/mapper after you get response from Retrofit which is possibly the easiest but again it will consume CPU and memory everytime you get a response.
I'm building an android app similar to a facebook app, aimed to display various information stored in a database.
I'm using on the server-side a REST API, which returns responses based on various POST requests, with a facebook token authentification.
And on the client-side, I'm using the volley library to deal with network requests. I've tried numerous possibities but I'm searching for the most elegant way of communicating with the server, and since this is a trivial case, I thought you could maybe help me with this one...
Since I'm always checking fb tokens, and making similar POST requests, I considered adding a Connexion objet, which creates a volley request when prompted with an execute(POST parameters...); method, and calls a callback method when the response has arrived.
But I'm struggling to decide whether I should create a SessionManager object (Singleton or not ?) which can process ALL the data from session related responses (like check login, login...) based maybe on codes (for example Error 5xx for every type of response), and DO the intents.
Or I should process these responses in every activity, and do the intents there. Knowing they can maybe repetitive.
In short, I'm looking for a best practice to apply when the app has to process common responses, and not so uncommon responses for example.
Keep all the logic in the activities ? Create objects ?
Don't hesitate to post your opinion on the subject !
Thank you very much.
EDIT : Ended up using a Connexion object to process all the requests (with volley). As for the Intents, I kept all that logic in the activities and haven't used another controller. The result was not ugly. Mainly because I used a secondary route which does the authentification, so the server ALWAYS responds with a big error if you're an evil hacker.
First of all I am not working with Volley but with the Apache HttpClient, this should not matter for your question though.
Having the code which handles the Post Requests in your Activities is a bad solution. See:
Single Responsibility Principle
Your idea with creating a SessionManager is really good though. You can handle all the stuff in the SessionManager and not bother with it in your Activities. Additionally you should add classes for different purposes than managing the session. If you get all friends from a specific user you should create a FriendsController or FriendsManager.
Processing the answers can be done in a single class too. I assume that you receive JSON from your API as response. Create one class that takes the response and returns a JSONObject.
Although it is far from perfect feel free to take a look at my app. I am currently learning Android / Java so it might not be as perfect as one might expect. The classes to handle POSTs are called YYYController and not Manager. But this is just a naming convention I use:
My Android Project
Your calls can return an enum in which you store the different Callback types:
class Enum Callbacks {
SUCCESS,
CREATED,
UNPROCESSABLE_ENTITY
}
In your application you can use them like this:
Callbacks response = SessionManager.login();
if (response == Callbacks.SUCCESS) {
//your login logic here
}
In my android app, I need to post JSON data to several REST APIs and get JSON data back for parsing. I want to use GSON to serialize/deserialize the data.
Each REST API has different input/output fields, should I define a separate class to hold data for each API request and response like this?
public class API1RequestData{
public String field1;
public String field2;
}
I am asking this, because if I am using python to construct the JSON request, I don't need to define classes, a dictionary will do.
I believe you should by design (I end up re-using them when I can though). This guarantees you don't send unnecessary data to the server.
If you are really worried about data consumption, i recommend you to:
Do not send null values to the server (just check if they arrive null);
Use integers for errors in the response, instead of booleanor string
Send only new stuff when refreshing some data (save some checksum/timestamp of the "data version" and check it)
...
It all depends on what your application needs. Sometimes it's not worth adding some design patterns that will slow down development in exchange for nothing
I created a base class that has all of the functions for post and get, then I inherit that class and override the collection part of the class. Part of every request is authentication, request type, and request body. Part of every response is response type, permission level, and the data. The data becomes a collection on most of the inherited classes. This works well for serialization and deserialization on both ends and using the base class keeps code maintenance to a minimum.
I've had other projects where I've done things differently for various reasons. Whatever works is good. If you have identically structured requests but the names are what is different, then just make one class and rely on context to know what it is. If the requests are structured differently, use different classes.
I'm currently using JSON (org.json) to serialize one of my data classes. When I pass it in a Bundle or with an Intent, I just call .toString() on the sender side and then recreate the class on the receiving side. From everything I've read so far, I should not implement Java's Serializable due to performance concerns. I'm in the process of rewriting certain portions of the app and I was considering making my data classes implement Parcelable and transfer them that way. What would the advantages be if I did it that way? Would it be preferable if I used the Jackson JSON library instead? Most of the JSON work is based on the API; server responds only with JSON. I also store some of the JSON for caching on the app side.
I think JSON is by far the most convenient mechanism for typical POJOs; and it seems unlikely that performance should be significantly worse that with Parcelable. Parcelable implementation could be more compact; but if that is problematic, you could even compress cached JSON payloads. So I would probably try out JSON first and see how it works.