Last Updated on September 21, 2018 by Aram
This article is a continuation for the Retrofit Tutorial in Android.
To make sure you follow up with the tutorial, I advise that you read my previous article Retrofit Tutorial in Android – Part 1 Introduction
So in the first part of the tutorial, we had an introduction to Retrofit library, discussing in brief about its powerful features, we started the tutorial with including the Retrofit library reference, creating the Retrofit Instance, preparing the Retrofit Interface that will match the API endpoints for the countries web service, and then we built our simple Regions/Countries app.
My main focus was to get you started with Retrofit and let you understand the concept behind using this library with its many easy to use features instead of using the OkHttp Library.
In this tutorial, I will show you how can you do a POST request using Retrofit.
So bear and focus with me so that you can get the best out of this tutorial.
Doing an HTTP POST Request
Usually, whenever you have a web service that is defined as POST, the intention behind it will be that this service will save/add data on the backend side, such as adding a user from a sign up form.
An HTTP POST request allows the consumer to apply a body to the request, a request body’s format can be defined by the Content-Type header.
In Retrofit, you don’t have to define this header specifically, because the Converter will do it for you. If you remember, in the previous article we used the GsonConverterFactory at Retrofit instantiation. This factory does the job on behalf of us.
So let me show you how can we do the POST Request using Retrofit.
Please note that I will not explain all parts of the code, as many steps have been explained in depth in the Part 1 of the Retrofit Tutorial in Android.
We will be doing our Post request to a public testing api reqres
Preparing the project and Retrofit-related setup
Start a new project, and import the needed retrofit libraries as the below:
1 2 |
implementation 'com.squareup.retrofit2:retrofit:2.3.0' implementation 'com.squareup.retrofit2:converter-gson:2.3.0' |
Then create the retrofit interface, name it IUsersApi
Now, we will create a Post request, for this we will use the annotation @POST and the annotation @Body to pass the needed model to the API. See the below
1 2 3 4 5 6 7 8 9 10 |
import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.POST; public interface IUsersApi { @POST("/users") Call<User> createUser(@Body User user); } |
Now, let’s create the User Model. Create a class with name User:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class User { private String name; private String job; private String id; private String createdAt; public User(String name, String job) { this.name = name; this.job = job; } public String getName() { return name; } public String getJob() { return job; } public String getId() { return id; } public String getCreatedAt() { return createdAt; } } |
After that we need to define our Retrofit Instance. This has been explained in the previous tutorial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import retrofit2.Call; import retrofit2.Callback; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class ApiManager { private static IUsersApi service; private static ApiManager apiManager; private ApiManager() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://reqres.in/api/") .addConverterFactory(GsonConverterFactory.create()) .build(); service = retrofit.create(IUsersApi.class); } public static ApiManager getInstance() { if (apiManager == null) { apiManager = new ApiManager(); } return apiManager; } public void createUser(User user, Callback<User> callback) { Call<User> userCall = service.createUser(user); userCall.enqueue(callback); } } |
Then we will extend the Application Class, to create our singleton Retrofit Interface.
1 2 3 4 5 6 7 8 9 10 |
public class MainApplication extends Application { public static ApiManager apiManager; @Override public void onCreate() { super.onCreate(); apiManager = ApiManager.getInstance(); } } |
Consuming the createUser Method
Now, we have the foundation to the Users API provided by reqres.in , we will consume the createUser method, to do a POST Request from the app.
Open activity_main.xml, and add 2 EditText widgets with 2 TextViews as Labels under each other and a Button. Make sure you change the activity_main layout to be LinearLayout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:labelFor="@+id/name" android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" android:text="Name"/> <EditText android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:labelFor="@+id/job" android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" android:text="Job"/> <EditText android:id="@+id/job" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:inputType="text" /> <Button android:id="@+id/save_user" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Save user" android:layout_margin="15dp"/> </LinearLayout> |
Now open MainActivity.java, and get reference to the EditTexts and the button, and add the ClickListener to the Button.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.Toast; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private EditText nameEditText; private EditText jobEditText; private Button saveUserButton; private ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); nameEditText = findViewById(R.id.name); jobEditText = findViewById(R.id.job); saveUserButton = findViewById(R.id.save_user); progressBar = findViewById(R.id.progress_bar); saveUserButton.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.save_user: User user = new User(nameEditText.getText().toString(), jobEditText.getText().toString()); progressBar.setVisibility(View.VISIBLE); MainApplication.apiManager.createUser(user, new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { progressBar.setVisibility(View.GONE); User responseUser = response.body(); if (response.isSuccessful() && responseUser != null) { Toast.makeText(MainActivity.this, String.format("User %s with job %s was created at %s with id %s", responseUser.getName(), responseUser.getJob(), responseUser.getCreatedAt(), responseUser.getId()), Toast.LENGTH_LONG) .show(); } else { Toast.makeText(MainActivity.this, String.format("Response is %s", String.valueOf(response.code())) , Toast.LENGTH_LONG).show(); } } @Override public void onFailure(Call<User> call, Throwable t) { progressBar.setVisibility(View.GONE); Toast.makeText(MainActivity.this, "Error is " + t.getMessage() , Toast.LENGTH_LONG).show(); } }); break; } } } |
Before we run the app , don’t forget to add the Internet Permission to your manifest file.
1 |
<uses-permission android:name="android.permission.INTERNET" /> |
And in the <Application tag , add the name to be MainApplication
1 |
android:name=".MainApplication" |
Running the app
Run the app, fill the Name and Job fields, and press Save User button. You should see the progress bar spinning underneath the button
And then, you should get the Toast Message telling you the name, job, id and TS for the created user. Where these values are turned back from the API, as the below screenshot.
I hope that was clear for doing a POST Request via Retrofit.
In the next tutorial I will explaining how can we pass request headers for the services that request them. We will access the Oxford Dictionaries API and do authenticated request call through passing header parameters: app_id and app_key
Stay tuned, and let me know if you like this article.
Tip: If you are interested to learn about RESTful web services architecture and gain a thorough understanding of its mechanics with an example to build and run RESTful web services in ASP.NET, then I recommend you check this comprehensive and well-written article: RESTful Web Services Tutorial by Alex Nordeen at guru99.com.
Bonus
Enjoy this wonderful rendition of an hour long Italian Baroque ‘concertos’ by the composer Giuseppe Sammartini
Thank you so much for your wonderful tutorial!