How write full stacks Apps with Kotlin (Springboot backend, Jetpack Compose Mobile)
Kotlin the primary android language since 7th May 2019, is a multipurpose programming language that keeps on evolving and getting better each year.
Kotlin is not just a programing language for your android development but a tool for everything you need, server side development with Ktor and Spring boot to MultiPlatform development with KMM and easy integration for data science with popular notebooks like Jupyter Notebook and Apache Zeppelin, it seems there is no stopping what Kotlin can do or what you can develop with it, for more on Kotlin, please read the docs on the official website.
In this simple walk through, we will build a simple Recipe Application to demonstrate how you can develop an API using Spring Boot and consume it with a Mobile Application using Jetpack Compose (The new kid on the block of Android Dev)
What this simple walk through is about:
- To give you a basic idea on how to development Server Side applications with Kotlin and Spring Boot
- Basic idea of consuming RestAPIs in jetpack compose with Ktor
- How to use the Navigation component in Jetpack
What this simple walk through is not about
- Architecture and best design for your API and Jetpack Project
- How to theme your mobile application
With that said, let’s get into it…
Server Side
Let’s start at my second favorite place on the Internet start.spring.io and generate a new spring project with Maven as the build tool (you can use Gradle, if you wish). Please add the dependencies as shown below
Now that we have our project generates, let’s fire up our IDE and import the project, once it syncs let’s add some more dependencies to pom.xml file, add OpenAPI dependency for Swagger
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.15</version>
</dependency>
At this point your pom.xml should look like this
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.paul</groupId>
<artifactId>RecipeService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>RecipeService</name>
<description>Bring the meals to life</description>
<properties>
<java.version>11</java.version>
<kotlin.version>1.6.21</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.15</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
<plugin>jpa</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
Let’s create some packages as shown below:
Next up, some Kotlin files and classes
Config Package
Entities
Repositories
Data
Service
Controller Package
Utils
PS: Don’t forget to write some test cases for your endpoint and services. The link to the Github repository is located at the end of the blog.
Android App with Jetpack Compose
If you don’t have any knowledge on what jetpack compose is, please read the official website. Let’s start a new project, PS you need the latest stable version of Android Studio version
Create a new Jetpack Compose project in android, after the project syncs. Create some packages as show below:
Let’s add the following dependencies to project
// build.gradle (project)
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.21'
Let’s add some Kotlin code to our Screens Package
The rest of the code is can be found in the Github project.
Credits: I usually use this solution for solving the serialization with Ktor since Kotlin does not provide a serializer for Any type.
Project Links
Mobile App Github Repo
Backend Github Repo
Happy Coding..