We are going to continue the Retrofit basics tutorial with the HTTP POST request together with the WordPress REST API, which allows us to send data to the server and register the user.
First in this chapter, we will create an interface for the Json API and there we will define the relative URL endpoint for the POST request and the needed arguments.
Then, we are going to create a singleton client for Retrofit. This client will hold the needed information for the authetication. Thenafter come the base url, the HTTP client and an instance about the JSON API.
So, let’s start coding. 😎
GitHub
If you haven’t done the previous chapters, then from GitHub you can download the starter project for this chapter.
000webhost.com
As a test website, we have prepared a sample domain with hosting. There we have installed WordPress and a plugin, Swagger which helps us to connect to the database of the website.
Later on, we will use the below login information to join to the database.
-
-
- Username: admin
- Password: inspire.coding
- Link: https://retrofitdemoapp.000webhostapp.com/
- Link to the API endpoints: https://retrofitdemoapp.000webhostapp.com/rest-api/docs/#/endpoint/get_wp_v2_users__id_
-
Step 1 – Create the Json API
Our first task is to create an interface for the Json API, where we will have all of the API calls.
Source: WikiPedia
Create a new package and the interface file
We will have the API interface inside of a new package, called “repository”. So, click with the right mouse button on the package of your project, then select New, then the Package option. Name the new package as “repository”.
Inside of the new repository package create a new “JsonWordPressApi” interface. Click on the package with the right moust button, then select New and the Kotlin file/class option.
The code for the POST request
The Retrofit library uses annotations to recognize, what is the purpose of the method, what it should do. In our case we will use two annotations.
The first one will be @FormUrlEncoded, which denotes that the request body will use form URL encoding. The fields should be declared as parameters and annotated with @Field.
The second annotation will be the @POST, which will identify a relative or absolute path, or full URL of the endpoint.
(This value is optional if the first parameter of the method is annotated with @Url.)
registerUser
Later on we will come back a bit to explain the endpoint in more detailes.
Step 2 – Create the Retrofit client
There are more possible solutions to implement the client of Retrofit. We will create a singleton object to avoid multiple instances about the above created API and the HTTP client.
So, create a new object inside of the repository package with the name of “RetrofitClient”.
Member variables
The object will have 2 private member variables.
The first one will hold the username and the password of the admin user. This admin user has all of the rights inside of the WordPress website.
The authentication
The second will be the base url. In the previous step we have defined the endpoint for the POST request. This comes from the Swagger REST API, what we have installed previously on the WordPress website. You can find there the base url also.
https://retrofitdemoapp.000webhostapp.com/rest-api/docs/#/endpoint/get_wp_v2_users__id_
Be careful, that the last character of the url string has to be “/”. Otherwise you will get an error and your app will crash.
The base url
The OkHttp interceptor
Next, we are going to define an interceptor and add it to the OkHttpClient.
Paste the below code after the two private member variables.
okHttpClient
Once the interceptors have been added to the OkHttpClient, we can now add the OkHttpClient to the Retrofit builder as you can seen below.
Builder of Retrofit
That was all about the client of Retrofit. You can close this window, we won’t add more codes there.
Step 3 – Internet persmission
To use the Retrofit library and the REST API calls, we have to request from the user a permission to use the internet.
For this, open up the AndroidManifest.xml file from the manifest folder and paste the below line before the <application> tag.
Internet permission
Step 4 – The repository
To follow the rules of clean code and the MVVM design pattern, we are going to separate the direct call of the POST method from the interface and the Retrofit client in a UserRespository::class. Here, we will have only the call, because of the SOLID principle, which is the separation of the concerns.
So, create a new Kotlin file in the repository package with the name of “UserRespository”.
Next, paste into the UserRespository::class the below code.
registerUser()
Note the suspend modifier of the method. It tells the compiler, that this is a suspend function, which is just a regular Kotlin and it indicates that the function can suspend the execution of a coroutine. It means, we are going to call these functions in a separated thread from the main thread to avoid the any freeze of the user interface.
Step 5 – The enum of status
Before we can implement the ViewModel, we will create an enum, which holds the status of the respons from the Retrofit client.
So, create a new package called “utils”, and there create a new Kotlin enum with the name of “Status”.
Paste into it the below lines.
enum class Status
Step 6 – The resource
Based on the status and the result of the API call, we can define three states, as we did it in the very last step. So, we will define a data class, which will have a companion object.
In the next step we will encapsulate the status of the request into the now difened resource data class.
The data class looks like below.
data class Resource
Step 7 – The ViewModel
The next step of the implementation of the ViewModel, which comes from the MVVM design pattern.
This ViewModel will hold the data, and will be responsible to get the actions from the UI and send it to the Retrofit client. From the other way, the ViewModel will notify the UI, when the data has changed.
New package and file
So as before, we will create a new package for the ViewModel. The name of it will be “viewmodel”.
When you have finished the new package, create a new Kotlin file there also, and name it as “RepositoryViewModel”.
The code
After the creation of the new package and file, we can start to implement the code.
First, we will create a private instance about the UserRepository::class.
private val userRepository: UserRepository = UserRepository()
Next, we will make two LiveData, which will hold the currently logged in user, and a message, which will be visible for the user in case.
The two LiveData
As you can see, currently we can’t set the values of the LiveData from outside of the ViewModel. Because of this, we will create two public methods, what we can call from another class.
Set the values of LiveData
Finally, the method what we will use to register the user. The name of it will be “registerUser()”.
registerUser()
Note the next two things
-
-
- liveData(Dispatchers.IO): this call will create for us a CoroutineScope. With this, we can call the suspend function from the repository.
The Dispatchers.IO means, that the body of the scope will run in a background thread. IO means data operations. - emit(): During the run of the request, we will tell for the UI that it is still running. When it is finished successfully or got an exception, then we will emit these results also.
- liveData(Dispatchers.IO): this call will create for us a CoroutineScope. With this, we can call the suspend function from the repository.
-
Step 8 – Extend the RegisterFragment
In the last big step, we are going to add the final code to the RegisterFragment::class. So, open it from the fragments package.
New variables
During the registration, we will need three strings. So, define them before the onStart() method.
var username = “”
var email = “”
var password = “”
Validate the strings
When we have the three strings, we have to validate the format of them. It means, we will define a new method, called “validateFields()”, which will give back a Boolean value. When it is true, then we can start the registration (POST) request. Otherwise the user will see the error message on the screen.
validateFields()
The click listener for the register button
Next, when the string fields are correct, then we pass them to the RepositoryViewModel::class using its register() method. It gives us back a LiveData, what we can observe.
When the request is finished successfully, then
-
-
- the Spinner has to be gone
- we will set the currently logged in user
- we will be redirected to the MainFragment
-
In case of error, the user will be notified about the error using a Toast.
When the status is loading, then just the Spinner will be visible.
Copy and paste the below click listener into the end of the onViewCreated() method.
setOnClickListener
The observer for the Toast messages
After the click listener, we have to define the observer as well to notify the user. So, paste the below line again at the of the onViewCreated() method.
observe the toast messages
Navigate to the login screen
When we have already a registered account, then we would like to login. Because of this, under the register button we have a text, which helps us to navigate to the LoginFragment.
This is the click listener for this text and goes also at the end of the onViewCreated() method.
Navigate to the login screen
Navigate to the register screen
The last thing before we can start testing the app is the navigation to the register screen from the login screen.
It is necessery, because currently the default screen is the login screen, when we open the app.
So, open up the LoginFragment from the fragments package, and paste there the below lines of code after the onCreateView().
Navigate to the register screen
Run the app
Finally, it is time to test the app. So, run it on your virtual or real device. Enter a test username, email and password, then press the register button.
Thenafter open the link of the WordPress site and check if the request was successful by navigate to the users.
GitHub
The source code is available on GitHub
Questions
I hope the description was understandable and clear. But, if you have still questions, then leave me comments below! 😉
Have a nice a day! 🙂