BlogAnnounced at MongoDB.local NYC 2024: A recap of all announcements and updatesLearn more >>
MongoDB Developer
Kotlin
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Languageschevron-right
Kotlinchevron-right

Mastering Kotlin: Creating an API With Ktor and MongoDB Atlas

Ricardo Mello9 min read • Published Feb 15, 2024 • Updated Feb 15, 2024
Kotlin
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Kotlin's simplicity, Java interoperability, and Ktor's user-friendly framework combined with MongoDB Atlas' flexible cloud database provide a robust stack for modern software development.
Together, we'll demonstrate and set up the Ktor project, implement CRUD operations, define API route endpoints, and run the application. By the end, you'll have a solid understanding of Kotlin's capabilities in API development and the tools needed to succeed in modern software development.

Demonstration

Demo of Kotlin and Ktor Project with MongoDB
As you can see above, our application will be capable of performing the operations depicted in the image. To accomplish this, we will utilize a data model structured similarly to the example provided:

Setting up the Ktor project

Ktor is a Kotlin-based, asynchronous web framework designed for building modern web applications and APIs. Developed by JetBrains, the same team behind Kotlin, Ktor simplifies the process of building web applications while offering robust support for asynchronous programming using Kotlin coroutines.
To begin our project setup, we’ll make use of the Ktor project generator.
Ktor Project Generator - Adjusting project settings
As depicted in the images, we need to configure parameters such as the project name, configuration file, etc.
In the subsequent section, we specify the following plugins:
  • Content Negotiation:  facilitates the negotiation of media types between the client and server
  • GSON: offers serialization and deserialization capabilities
  • Routing: manages incoming requests within a server application
  • Swagger: simplifies API documentation and development
Ktor Project Generator - Adding plugins
Once all settings are in place, simply click “Generate Project” to proceed with creating our project.
After importing the project, let’s proceed by opening the build.gradle.kts file to incorporate additional dependencies. Specifically, we'll be adding dependencies for the MongoDB server-side Kotlin driver and Koin for injection dependency.

Implementing CRUD operations

Before creating our project, let’s organize it into several packages. To achieve this, we’ll create three packages: application, domain, and infrastructure as shown in the image below:
Project structure
Now, let's create a package called entity inside domain and include a file named Fitness.kt:
domain/entity/Fitness.kt
As you can observe, our class has an error in the toResponse() method because we haven't created the FitnessResponse class yet. To fix this issue, we need to create the FitnessResponse class. Let's take this opportunity to create both FitnessResponse and FitnessRequest. These classes will handle the data exchanged in HTTP requests related to the Fitness entity. Inside the application package, create request and response packages. Include the FitnessRequest and FitnessResponse classes in each, respectively.
application/request/FitnessRequest.kt:
application/response/FitnessResponse.kt:
If everything is correct, our structure will look similar to the image below:
Project structure
Now, it’s time to create our interface that will communicate with our database. To do this, within the domain package, we will create another package called ports, and subsequently, the FitnessRepository interface.
domain/ports/FitnessRepository:
Perfect! Now, we need to implement the methods of our interface. We'll access the infrastructure package and create a repository package inside it. After that, create a class FitnessRepositoryImpl, then implement the methods as shown in the code below:
infrastructure/repository/FitnessRepositoryImpl
As observed, the class implements the FitnessRepository interface and includes a companion object. It receives a MongoDatabase instance as a constructor parameter. The companion object defines a constant named FITNESS_COLLECTION, with a value of "fitness," indicating the name of the MongoDB collection where operations such as insert, find, delete, and update are performed on fitness-related data.
If everything is correct, our structure will be as follows:
Project structure

Developing API endpoints

To create our endpoints, understanding routing is crucial. In Ktor, routing dictates how the server handles incoming requests to specific URLs, enabling developers to define actions or responses for each endpoint. Before proceeding with the creation process, let’s briefly review the endpoints we’ll be constructing:
  1. GET /fitness/{id}: Utilize this endpoint to fetch detailed information about a specific fitness activity based on its unique identifier (ID).
  2. POST /fitness: With this endpoint, you can effortlessly add new fitness activities to your tracker, ensuring all your workout data is up-to-date.
  3. PATCH /fitness/{id}: Need to update or modify an existing fitness activity? This endpoint allows you to make targeted changes to specific activities identified by their unique ID.
  4. DELETE /fitness/{id}: Finally, this endpoint empowers you to remove unwanted or outdated fitness activities from your tracker, maintaining a clean and accurate record of your fitness journey.
Now that we know the methods we will implement, let's create our class that will do this work. Inside the application package, let's create a new one called routes and the file below with the name FitnessRoute.kt with the content below:
application/routes/FitnessRoutes.kt
As you can observe, we’ve set up method calls and utilized call to define actions within route handlers. Ktor allows you to manage incoming requests and send responses directly within these handlers, providing flexibility in handling different request scenarios. Additionally, we're utilizing Koin for dependency injection in the FitnessRepository repository.
Now, before we proceed to run the application, we need to install the Koin dependency and incorporate it as a module.
Modules in Ktor are used to organize and encapsulate functionality within your application. They allow you to group related routes, dependencies, and configurations for easier management and maintenance.
To accomplish this, open the Application.kt class and replace all of its code with the one below:
com.mongodb.Application.kt
Let’s break down what this code is doing into three main sections for easier understanding:
  1. ContentNegotiation configuration: We’re setting up ContentNegotiation to handle JSON serialization and deserialization. Specifically, we’re using Gson as the default JSON formatter, ensuring seamless communication between our application and clients.
  2. Dependency injection with Koin**:** In the subsequent section, we’re integrating Koin for dependency injection management. Within the first module, we establish the connection to MongoDB, retrieving the URI and database name from the configuration.conf file. Subsequently, we define injection for the FitnessRepository.
  3. Routing configuration: During the routing phase, we configure the Swagger API route, accessible at /swagger-ui. Furthermore, we specify our route for handling Fitness-related operations.
Great. Now, we need to make the final adjustments before running our application. First, open the application.conf file and include the following information:
resources/application.conf
Notice: These variables will be used at the end of the article when we run the application.
Very well. Now, just open the documentation.yaml file and replace it with the content below. In this file, we are indicating which methods our API will provide when accessed through /swagger-ui:
resources/openapi/documentation.yaml
The final adjustment is to delete the plugins folder, which contains the HTTP.kt , Routing.kt, and Serialization.kt files, as we have already included them in the Application.kt class. Additionally, delete the ApplicationTest class since our focus here is not on tests. We can discuss testing another time. After these changes, your structure should look similar to this:
Project structure

Running the application

To run our application, we need a connection string from MongoDB Atlas. If you don't have access yet, create your account.
Once your account is created, access the Overview menu, then Connect, and select Kotlin. After that, our connection string will be available as shown in the image below:
MongoDB Atlas - Cluster connection string
With the connection string in hand, let's return to IntelliJ, open the Application.kt class, and click on the run button, as shown in the image:
Running the application
At this stage, you will notice that our application encountered an error connecting to MongoDB Atlas. This is where we need to provide the MONGO_URI and MONGO_DATABASE defined in the application.conf file:
To do this, simply edit the configuration and include the values as shown in the image below:
Click “Apply” and run the application again.
IntelliJ Run Settings
Attention: Remember to change the connection string to your username, password, and cluster in MongoDB Atlas.
Now, simply access localhost:8080/swagger-ui and perform the operations.
Swagger Dashboard
Open the post method and insert an object for testing:
Swagger Responses
We can see the data recorded in our MongoDB Atlas cluster as shown in the image below:
MongoDB Atlas Document Explorer

Conclusion

MongoDB Atlas, Ktor, and Kotlin API service together form a powerful combination for building robust and scalable applications. MongoDB Atlas provides a cloud-based database solution that offers flexibility, scalability, and reliability, making it ideal for modern applications. Ktor, with its lightweight and asynchronous nature, enables rapid development of web services and APIs in Kotlin, leveraging the language’s concise syntax and powerful features. When combined, MongoDB Atlas and Ktor in Kotlin allow developers to build high-performance APIs with ease, providing seamless integration with MongoDB databases while maintaining simplicity and flexibility in application development. This combination empowers developers to create modern, data-driven applications that can easily scale to meet evolving business needs.
The example source code used in this series is available in Github
Any questions? Come chat with us in the MongoDB Developer Community.

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Tutorial

Beyond Basics: Enhancing Kotlin Ktor API With Vector Search


Mar 25, 2024 | 9 min read
Quickstart

Unboxing Jetpack Compose: My First Compose App


Apr 02, 2024 | 5 min read
Tutorial

Introduction to the Realm SDK for Android


Sep 23, 2022 | 4 min read
Tutorial

Getting Started with the MongoDB Kotlin Driver


Oct 12, 2023 | 9 min read
Table of Contents