Mapping rest model to domain model in Android - android

I want to keep my domain model and rest model separate so that I don't have to worry about changing the domain model when rest API changes. Also, I get to work with UI-friendly format by converting rest model to domain model.
I use retrofit to consume Restful web service. In onResponse(), I am mapping the rest model into domain model. I hate instantiating bunch of objects on the main thread. What are some clean ways to map not on main thread?
String username = "test";
Call<User> call = apiService.getUser(username);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
int statusCode = response.code();
User user = response.body();
// Want to convert rest model to domain model for my use
Account account = AccountMapper.map(user);
}
#Override
public void onFailure(Call<User> call, Throwable t) {
// Log error here since request failed
}
});

Generally you want a converter. The converter's job is to interpret from the external Api to your domain context/models. Converters can be implemented as "Factories". You pass the factory method the right parameters and it'll return to you something that your domain understands/can use.
Now, when you say "not instantiating on the main thread": It sounds like you have answered your own question because that sounds like you are suggesting concurrency through threads. Unless you concurrently spin up a new thread, you can move the code around but you'll always be on the "main" thread.

after you get the response just call map{ someMapper().map(from, to)}
here would be the general interface for all your mappers:
interface Mapper<FROM, TO> {
fun map(model: FROM): TO
}

Related

Send lots of data from Android

I have an application in Android, it sends several data in short time. Aprox. 2500 request.
This process is very time-consuming.
What advice can you give me to improve the time?
Thanks
You can use multiple Thread to send data to the server in the background.
If you are updating UI component after the execution use AsyncTask. But you have to run AsyncTask parallelly. You can do that by AsyncTaskCompat.executeParallel(Your AsyncTask);
If you wish to send data even your app closed. You can use service.
I'd recommend using Retrofit. It handles a lot of threading issues you might be struggling with.
Here's an example from their website.
You'd create an interface for the API you're looking to receive:
public interface GitHubService {
#GET("users/{user}/repos")
Call<List<Repo>> listRepos(#Path("user") String user);
}
You build a retrofit class
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
And finally you get a call object:
Call<List<Repo>> repos = service.listRepos("octocat");
Consuming the call object requires enqueueing a Callback. Here's an example using a different Retrofit service (TaskService in this case):
TaskService taskService = ServiceGenerator.createService(TaskService.class);
Call<List<Task>> call = taskService.getTasks();
call.enqueue(new Callback<List<Task>>() {
#Override
public void onResponse(Call<List<Task>> call, Response<List<Task>> response) {
if (response.isSuccessful()) {
// tasks available
} else {
// error response, no access to resource?
}
}
#Override
public void onFailure(Call<List<Task>> call, Throwable t) {
// something went completely south (like no internet connection)
Log.d("Error", t.getMessage());
}
}
Source

How can I parse the response through Retrofit 2 if response can be both a JSon/HTML?

Hi I'm working with an API, which returns the login page when the session token is invalid/JSON response if the session is valid. How can I implement this with Retrofit, ie having multiple response types ?
P.S It's an old API and it can't be changed. I'm new to retrofit, I'll be really grateful of your help.
Would post this as comment as it's more a suggestion then actual answer but here it goes:
(If you're completely new to Retrofit leave a comment to explain it in more detail)
You could make your Call return a Response like so:
#GET("login/endpoint")
Call<Response> getLogin();
than you can make the call like this
Call<Response> getLogin = ApiService.getLogin();
getLogin.enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Response> call, Response<Response> response) {
//here you can access Response.body() and use it to determine wether it's json or html and react accordingly
}
#Override
public void onFailure(Call<Response> call, Throwable t) {
//todo: error message
}
});
note: the Response i've used is from the OkHttp Library.
If this doesn't work you could try to make your own converter which has a check for html/json and adding it in the creation of the retrofit instance. i'm not entirely sure how you can go about with that but this seems to have a general idea: custom converter from futurestudio.
If you need more guidance/clarification please let me know i'll be able to answer later today.

How to implement POST method in AsyncTask to write JSON data through API in android studio?

I want to POST JSON data having nested objects in it with the help of Asynctask in android studio, but I don't have good knowledge of API implementation in android studio. I am all new in android studio. I have successfully POST this data from POSTMAN, but I am not able to implement the code for it, also I don't have any tutorials for Asynctask. Please help me to implement code for this.
This is my Json data having nested Objects in it:
You don't need Async, Volley does it in the background for you. Put your JSONObject in the method instead of 'new JSONObject'. And YourURL - i.e '/api/route/'.
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest request_json = new JsonObjectRequest(YourURL, new JSONObject(params)),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
//Do what you want on response
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//If there's an error...
}
});
//Add process to queue to get JSON in background thread
queue.add(request_json);
Nowadays a better/simpler approach would be to use a libary like Retrofit to do all the magic for you.
You can simply send a Java instance model to an API endpoint. Retrofit takes care of converting it to json when using the GsonConverterFactory class and sends the json to the endpoint you provided with the given HTTP method.
Best and Simple Library for Implementation for API services by third party library made by Square, Retrofit a Easy HTTP Client.
Why Retrofit? because, Retrofit automatically creates the background thread ,Parse the Json using GSON converter and get a call success and Failure call back directly on main thread. Without writing too much boiler plate code of AsyncTask and Parsing JSON and getting the result on main thread.
Make Retrofit Client.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
RetrofitInterface service = retrofit.create(RetrofitInterface.class);
Make Method in RetrofitInterface.
#POST("users/new")
Call<User> yourMethod(#Body UserType user);
Now Call your method and It will make your success and Failure Callback method
Call<List<Repo>> repos = service.yourMethod("octocat");
And then Call enque method to automatic create background thread.
repos.enqueue(new Callback<List<Repo>>() {
#Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
}
#Override
public void onFailure(Call<MainResponse> call, Throwable t) {
}
});

Android, Retrofit 2 POST request

I'm new to Android developing and I don't know how to do this, I've searched on the internet, but everything I've tried so far doesn't work. What I'm trying to do, is to send string to the server and the key must be "interval=". This is what I have so far, but it doesn't work. I'm getting string time2 from spinner, but for now it doesn't matter, because I know that the spinner part works and POST doesn't.
PostInterface service = retrofit.create(PostInterface.class);
service.postTime(time2);
and interface
#FormUrlEncoded
#POST
Call<Response> postTime(#Field("interval=") String time);
What I'm supposed to do net and how can I test it with http://requestb.in/ (never used it before, I just saw it can be used for POST testing)?
Why do you use retrofit in the first place ?
It's a good library, but if you're new to Android, i suggest to start with HttpClient.
In your sample, the execute method was not called.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://requestb.in/")
.addConverterFactory(GsonConverterFactory.create())
.build();
PostInterface service = retrofit.create(PostInterface.class);
Call<Response> call = service.postTime(time2);
call.execute()
In your interface (replace xxx by the token given by requestbin)
#FormUrlEncoded
#POST("xxxxxxx")
Call<Response> postTime(#Field("interval=") String time);
ps: Be aware that you should not launch any http calls on the main thread.
if you are posting a form field, you should remove the "=" from "interval="
fields are key and values, no need for the "="
if you want a test client for posts and get you can try postman
please clarify your question more if this is not what you expected as an answer
as #Mickael Monsang Answer
dont' use call.execute directly better use
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<Response> call, Response<Response> response) {}}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
}
});

How to connect android app to PrestaShop?

i already looked at most of the questions related to prestashop.Some of them is saying that there is no api for prestashop.look at this link
http://online.fastchef.in/api/customers/12?output_format=JSON
it is giving result in json form.only thing is to parse this form.but still m getting error
My Code:MainActivity
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
int id=Integer.parseInt(mEditText.getText().toString());
PrestaShopClient client =retrofit.create(PrestaShopClient.class);
Call<Customer> hj=client.getCustomer(id);
hj.enqueue(new Callback<Customer>() {
#Override
public void onResponse(Call<Customer> call, Response<Customer> response) {
int status = response.code();
Customer customer = response.body();
mTextView.setText(customer.getFirstname());
}
#Override
public void onFailure(Call<Customer> call, Throwable t) {
}
});
PrestaShopCLient:
public interface PrestaShopClient {
#GET("customers/{id}?output_format=JSON")
Call<Customer> getCustomer(#Path("id") int id);
}
help me out guys...this problem took my day nd half ;(
We suggest you to create a separate web service that will communicate with your android app and fetches and passes data in JSON format.
Web service means a PHP file that is present inside your PrestaShop installation. It performs operations on the basis of received requests and returns the data in JSON format that can be further decoded by your android app for respective functionalities.
You can download a web service from the following link
Prestashop Android App

Categories

Resources