Create Web Application With Ktor
Its easy to develop a web application using Ktor, In this article I am going to explain the tools we need and the steps for developing a small CRUD based web application using Ktor. I will take Employee entity as an example to demonstrate this application. We are going to use below frameworks/libraries.
- Ktor framework: Develop asynchronous servers and clients.
- FreeMarker: Template engine to generate text output. We are using it for HTML pages.
- H2 database: In-memory and very fast database.
- Exposed SQL library: Light weight library for database access.
If you are new to Exposed and Ktor framework then please go through below series of articles. These articles will explain them in more details.
We are going to develop web pages using Freemarker and these pages will perform add/edit/delete operations on the employee entity. Lets get started.
- Create Kotlin project
- Add and configure Ktor framework
- DAO layer for database
- Configure FreeMarker
Please note that this whole project is available in github
Create Kotlin project
Execute below command to create an empty gradle Kotlin project. Once the project is created then import it into your favorite editor.
I executed this command on Gradle 5.2.1 version. You can choose to create kotlin project with any other build tool.
This command will create new project with standard folder structure with default App.kt file.
Add and configure Ktor framework
Adding Ktor framework to the project is easy, just add below dependencies to your build.gradle
Configure Netty embedded server
Go to App.kt and update it with below code.
embeddedServer function will initiate and run the embedded server and we passed below arguments to it;
- Server instance type; We passed Netty. Ktor support Jetty and Tomcat as well.
- Port number on which the server will listen.
- Lambda instance of Application. Right now it is empty but we will add more details to it in next sections.
DAO layer for database
We are using Exposed to connect and perform SQL operations on H2 in-memory database. We need to include required dependencies in the build.gradle so go to build.gradle and add below dependencies.
To learn more about SQL library Exposed please read this article
Create Model and Mapping
We are using Employee entity as an example so lets create a new package net.thetechstack.model and add Employee.kt with below code.
This is a simple data class with four fields. We want to maintain id, name, email and city for the Employee so the constructor needs all these values.
Create a new package net.thetechstack.dao and add Employees.kt file with below content;
Employees is the mapping object for Employee. This object will give enough information for Exposed to map fields with the database table. This object acts like a object to table relational mapping.
Instead of directly performing database operations we are creating DAO layer. DAO (Data Access Layer) will wrap all database operations in it. Create DAOFacadeDatabase.kt file in net.thetechstack.dao package with below code.
We created an interface, this defines the contract for DAO layer. We added all the methods needed to perform CRUD operations. With in the same class lets implement this interface.
DAOFacadeDatabase needs Database instance. We wrapped all query statements with in the transaction because Exposed needs all the database operations to be performed with in a transaction.
To understand more about Exposed please read this article
Now we have our DAO layer ready.
Integrate Exposed with Ktor
Lets integrate DAO layer with Ktor. We need to instantiate DAOFacadeDatabase by passing H2 in-memory database instance. Update Application.kt with below code;
Instantiated DAOFacadeDatabase by passing H2 database instance and used this instance to create the tables by calling init()
Update build.gradle with below dependency to add support for FreeMarker templates;
We will save all our FreeMarker templates in resources/templates directory so create this directory under ktor-freemarker/src/main/
We installed FreeMarker feature on the request and response pipeline by passing FreeMarker configuration to install function. We are going to save all our FreeMarker templates in templates folder so we passed this to FreeMarker configuration. Now FreeMarker will check templates in src/main/resources/templates folder
We need three template files;
- template.ftl: This is the base template of our application. This contains the page layout.
- index.ftl: Main page with list of all employees and gives options to add/edit/delete employees.
- employee.ftl: Allows us to add/edit employee.
This is a simple HTML page uses Bootstrap CSS for styling and has some FreeMarker directives macro and nested.
Macro is used to store reusable templates and we can give it a name to refer them later. In below code I created a macro with named test. This macro contains reusable block, in this case it is having Hello with in p tag. If I want to output Hello then we call this macro <@test/> then the macro will be executed. Below code will output ‘Hello’ two times.
Macro can take input parameters and we can use them with in the template.
More information on the macro is available on the FreeMarker site.
Instead of Macro having its own content we can pass content to it using Nested. Macro acts like a border around the nested. In below example we are passing ‘Hello’ to it and macro will replace <#nested> with the content.
In template.ftl we uses macro and nested to define our web page structure. We called our macro as mainLayout now we can use this in other template files.
We imported template.ftl as layout and used it in index.ftl. In this page we display all employees and allows users to add/edit/delete employees. list directive will allow us to iterate employees. To add/edit we are passing action query parameter and for delete we are passing id
This template is for new/edit employee records. action field in the form is used to maintain the type of action and id contains the employee id which server can use to update it. On submit form will be submitted to /employee.
Update App.kt with below code to create HTTP end-points.
- /: Loads index.ftl by setting all employees in employees key. We use this key in the template to iterate and display all employees in the HTML table.
- GET: Loads employee.ftl. To handle edit we fetch the employee record and set it in the map.
- POST: Loads index.ftl after the action. new will create new employee and edit will update the record.
- /delete: Deletes employee and loads index.ftl
Below is the demo run of the application.
We developed a simple web application using Ktor framework and used many other libraries to perform CRUD operations on an entity.