Using Ktor for creating REST APIs for mobile (part 2)

Tram Ho

Continuing after Part 1, here we will dive into the settings and define classes and functions from IntelliJ to handle client-side API calls.

Building the Model class

To interact with the data stored from Postgres we need to build the corresponding model classes in conjunction with the use of the repository . As described from part 1, we will need to build two classes User and Todo

First we create a folder called models and define a User class with the following content:

This class is used to create a User with the required components, including email, name and password in the form of a hash, which helps to increase database security

Next in the models directory we create a class called Todo :

This class is effective for declaring the to-do information of a user, with parameters such as the user ID, the content of the to-do job, and the status of the completed job.

Building the Database classes

In this step we will create classes to help interact with the database tables.

First we create a folder called repository to store these related classes. Next we create a file named Users to help create the user table on the database, the file has the following content:

The above class will help us create a user object with 4 columns: id, email, name and password. This makes it possible to save user information into the database easily.

Next, in the repository folder, we create another Todos object with the following content:

This class will help create the Todos object with the link to the user id in the Users table.

Next, we create a classs named DatabaseFactory to help create necessary tables and basic settings to connect to Postgres database.

The above class will contain 3 functions:

  • Init () function: initiates connection to the database and creates 2 tables, Users and Todos
  • Hikari () function: set the parameters required for connecting to the database, the parameters we have configured in the previous step include JDBC_DRIVER , JDBC_DATABASE_URL . If we use a different account than the default postgres account, we need two additional parameters: DB_USER , DB_PASSWORD to help authenticate the connection to the database.
  • DbQuery (block: () -> T) : uses Coroutines mechanism to run function calls to database in IO thread, helping server processing tasks without being slow and interrupted.

Create Repository for managing functions that call to Database

In this step we will define methods to access and manipulate Postgres database from within IntelliJ project.

To do this in the repository folder we add an interface named Repostiory and declare the methods as follows:

We can see this inteface includes methods: adding users, finding users by id and email, adding jobs and getting user lists. All functions use Coroutines mechanism to make the operation run asynchronously, without interrupting the server.

Next we will implement the installation of these methods. At the repository folder we create a file called TodoRepository to start the installation, the content is as follows:

Here we see the addUser function will receive the input parameters as email string and password. Based on the markings inside the body of the function we can see that it includes the main steps:

  1. Use the InsertStatement statement of the Exposed library we previously declared in the build.gradle file to help add data to the Postgres database.
  2. dbQuery uses the Coroutines mechanism to run database manipulation functions.
  3. Use the insert statement available from the Table class to proceed with adding a record to the table.
  4. Implement the rowToUser function to serve the conversion of data types from ResultRow to User .

The remaining functions such as findUser , addTodo , getTodos follow the same mechanism as above.

Build classes for User authentication

When working with user-related data, we need to build authentication classes to help the server build security and serve the right senders. In the previous project creation step we chose the authentication method as JWT , now we will create methods based on this method.

First, we create a folder called auth . From that directory, create the Auth.kt file with the following content:

The above file has the effect of retrieving the hashKey through the environment variable SECRET_KEY we created from the previous step and a function to hash any string using the HmacSHA1 algorithm.

Next in the auth directory, we create a JwtService.kt file with the content:

This file helps us create a JWT service that validates client requests. The generateToken function creates a token used for authenticating user requests after the user has successfully logged in. This token chain will expire in 24h.

Finally, in this auth directory, we create an additional MySession data class to store the user’s session , the content is the user’s id.

Update the configuration for running Application

In this step, we will use the classes defined above to reconfigure the running server.

In the Application.kt file, we replace the MySession class with the Mysession class we just created. Below the install (Sessions) command, add the following code:

The above code works for database initialization and the authentication of JWT we have built in the previous step

Next in the install (Authentication) section, we update the content to use JWT service to verify requests from the incoming clients.

The above function is to verify whether the user’s call is valid or not based on the user id from the saved database and whether the id of the submitted user exists.

Finally, we rebuilt the server and made sure we could see the Hikari- related logs and be able to connect the database successfully without any errors.

Building the routes

In this step, we will build routes for the client to make requests to the server, along with the corresponding handling of the incoming requests to return the results to the client.

The first is in the Application.kt file, we create a prefix path for the Route, this is not required but is recommended to have updates for the server later we will easily manage routes and maintenance. . We add the following code at the end of the Application.kt file

We will begin to build the routes related to the user. Create routes routes to store related files, then create a UserRoute file, we import the related libraries at the top of the file to avoid the problem of choosing the wrong library as follows:

Next, define the route links related to the users

For each Route path, we create classes to handle the functions related to it, here we have 2 paths, “users / login” and “users / create”, we will declare two classes respectively. UserLoginRoute and UserCreateRoute are as follows:

We see that each definition will have 3 parts:

  • KtorExperimentalLocationsAPI : used to remove warning when compile code
  • Location (USER_CREATE): Specify the Route path to be installed
  • class UserCreateRoute: defines the class that handles execution when the client calls the corresponding Route

Next, we install the UserCreateRoute and UserLoginRoute sections as follows:

Analysis of the UserCreateRoute function shows the following jobs:

  1. Define an extension function of the Route class named users. This function takes input parameters as repository, JWT serveice and a hash function.
  2. Initialize a route with the POST task
  3. Make a call to get the parameters passed when the request
  4. Perform password, displayName, and email check parameters, if not, return an error code
  5. Create a hash string from the received password
  6. Execute the command to add a user to the database

With the UserLoginRoute function, the check is corresponding, receive email and password. Then check the email and password after the hash exists in the database. If it returns successfully, otherwise it returns an error.

Next, in the routes directory, we create TodosRoute.kt file to build routes and handle related to Todo task list, content as below:

It basically consists of two jobs, using the POST method for adding a user’s job to the database, and a GET method for getting the job list from the user id passed from the request. Here we note that it is possible to use the same route for 3 different methods: POST, GET or DELETE.

Basically, we have built the necessary methods for handling server-side routes. The final step is to inform the server that we can accept requests for calls. To do this, open the Application.kt file again and navigate to the routing stream, we will add two built-in route functions:

At this point, we have completed the basic server construction, the next step we will check its operation.

Check server running

To perform a test to see if the APIs are working correctly, use a great tool, Postman ( ), to run the experiment.

After installing Postman , we proceed to test the creation of a user with the following information:

  • Method: POST
  • Path: localhost: 8080 / v1 / users / create
  • Body: with 3 parameters displayName , email , password

After entering all the information, we click Send . The information returned will be a token chain as shown below

We will proceed to save this token chain, used for subsequent visits of this user, to perform we open the Test tab and type the following command line

The above command line helps us store the token in a variable named jwt_token .

Next we will actually call the login for the user with the above registered information, we set up on Postman as follows:

  • Method: POST
  • Path: localhost: 8080 / v1 / users / login
  • Body: with 2 parameters email , password

If the token information is received that the login has been successful, see the illustration below

For the user who has successfully logged in, we will run the API to create a Todo list of that user’s jobs. First we need to authenticate the user information logged in by adding to the Authorization tab a string of tokens named jwt_token defined in the previous step.

Next create the following information:

  • Method: POST
  • Path: localhost: 8080 / v1 / todos
  • Body: with 2 parameters todo , done

When the steps run successfully, we will see the results returned as shown below

To get to the Todos list, we only need to convert the method from POST to GET .

At this point we can successfully test the 4 APIs we just created from the server.


Share the news now

Source : Viblo