Sample Ktor app using a functional stack

Overview

samstack

This is a template project you can clone and use as a basis for your own Kotlin based microservices.

This application structure is my personal preference. I do not claim this is the best approach (whatever that means), but simply that it works for me and has seen success at several companies I have worked at. This is an opinionated project and as such will not appeal to all.

I am a mild functional programming advocate, and my viewpoints are influenced by functional programming, but try to avoid the more advanced FP features that don't translate well to Kotlin.

Opinions

  • No dependency injection. You simply do not need it.

    • It is trivial to pass dependencies through the constructor. Services should be small enough that you don't have layers upon layers of "services" where passing dependencies around becomes a burden.
    • When you use constructors as they were intended, you never have to try and work out where a "bean" is being instantiated.
  • Config as data classes.

    • Easy to test because you can simply create the config values you want in tests and pass in an instance of the data class.
    • No confusion as to where values are being pulled from.
  • Tests should be real tests

    • No mocks. Ever. You don't need them (caveat - you might need them in some tiny edge cases, like testing a legacy Java interface with 200 methods).
    • Test your endpoints by using a framework that treats requests as simple objects.
    • Use test containers for real databases.
    • Use embedded HTTP servers for upstream dependencies.
  • Functional error handling

    • Don't throw exceptions unless it's truly exceptional. Expected errors, such as invalid json, are not exceptional.
  • Avoid interfaces for services and datastores

    • You don't need an interface for your database code. You're not going to need to mock them, and the logic is bespoke.
    • A good rule of thumb in my opinion is, if you have an implementation of an interface called MyInterfaceImpl then you don't need the interface because you have no natural name for the implementation.
  • Avoid ORMs

    • Unless you have a ton of CRUD to write, it's easier to just write SQL by hand.
    • Spring JDBC Template is a simple set of helpers around JDBC calls.
  • Don't use Strings for all your types

    • Avoid so called stringy-typed development.

Libraries

  • Kotlin - Running the latest Kotlin release.
  • ktor a Jetbrains Kotlin based HTTP framework that natively supports coroutines. Provides http-as-a-function (almost), and a great in-memory test server. Lacks swagger integration.
  • Hoplite a Kotlin data-class-as-config loader that provides cascading fallback of config files. Config is loaded in regular data classes that you define and can pass about. This allows for easy testing, as you can provide test-time values by simply creating instances of those data classes.
  • Kotest Kotlin test framework that supports nested test layout, coroutines, idiomatic Kotlin assertions, test-container extensions, property testing, data driven testing, non-deterministic helpers, and more.
  • Micrometer Metrics collection with integration with datadog / grafana, etc and most Java libraries come with Micrometer adapters to collect metrics. many/most Java libraries.
  • Hikari High performance and robust JDBC pooling library. The go-to JVM based connection pool library in 2022.
  • Tabby - a tiny functional programming accessory kit. Essentially a set of extension functions for Result that help fill in the gaps on Result.
  • Arrow - a functional programming accessory kit. Useful for resource management.
  • Kotlin Logging - a simple project that wraps slf4j but makes it easier to define a kotlin logger as a top level function.
  • Logback - a simple alternative to log4j.
  • Cohort A spring-actuator style plugin for Ktor. Useful for probes for kubernetes services.
  • Optio A validation library for Kotlin that takes the "parse don't validate" approach.
  • TestContainers Creates disposable containers for tests, so you don't need to mock database code, because you can test against the real thing.
  • Flyway Versioned database migrations, that you can also apply to your tests.
  • Spring JDBC Template Small set of helpers for working with JDBC calls.

Structure

  • App is your 'god' object. It contains config parsed by Hoplite, a Micrometer registry backed by datadog, a database java.sql.DataSource. Any dependencies you need to share should be created here.
    • The micrometer registry comes preconfigured with JVM metrics such as memory, cpu and diskspace.
    • The datasource is backed by a Hikari connection pool. Configure defaults in the database.yml files.
  • main - This is the starter function that sets some defaults and launches ktor
  • module - this contains a single logical grouping of ktor endpoints and plugins.

Modules

  • myservice-domain - place your domain classes here so they are shared between datastores and services
  • myservice-datastore - place your database or cache repositories here
  • myservice-services - place your business logic here
  • myservice-endpoints - place your endpoints in here
  • myservice-app - an assembly module that builds a docker image for deployment. Config files and logging configuration lives here.

Config

We define a base file, called application.yml which contains defaults that don't change between environments. For example, port numbers or cache ttls.

Then we have a separate file per environment in the format application-ENV.yml eg application-staging.yml

This app uses the powerful data-class-as-config approach from Hoplite. Files are loaded in a cascading fashion - earlier files (as defined in App) override values in later files. The file are converted to data classes and any missing values or conversion errors are immediately flagged on startup.

AWS secrets manager support is enabled by adding a config key in the form secretsmanager//:mykey which you can see in application-prod.yml for example.

Running

Startup docker docker-compose up from the root of this project. This will start up a mysql database.

Run the main method located in the app module. This starts up a HTTP interface on the port defined in application.yml. This ktor based http server is configured to return JSON using Jackson.

Three endpoints are included:

  • /health returns a 200 OK suitable for use in k8
  • /random returns a random Wibble instance
  • /database returns all wibbles from the database (you need to create the wibble table and add your own wibble!)
CREATE TABLE wibble (
   a TEXT,
   b INT
);

INSERT INTO wibble (a, b)
VALUES ("foo", 1),
       ("bar", 2 ");

Deployments

Executing ./gradlew dockerBuildImage will build a docker image ready for deployment.

You might also like...
📒 NotyKT is a complete 💎Kotlin-stack (Backend + Android) 📱 application built to demonstrate the use of Modern development tools with best practices implementation🦸.
📒 NotyKT is a complete 💎Kotlin-stack (Backend + Android) 📱 application built to demonstrate the use of Modern development tools with best practices implementation🦸.

NotyKT 🖊️ NotyKT is the complete Kotlin-stack note taking 🖊️ application 📱 built to demonstrate a use of Kotlin programming language in server-side

Kotlin TodoMVC – full-stack Kotlin application demo

Kotlin full stack TodoMVC This project is an example implementation of the TodoMVC app written in Kotlin. More specifically, it's the Kotlin port of t

Full stack examples of how to use Hotwire JS in Kotlin services

hotwire-kt A collection of Kotlin examples using the Hotwire JS framework to build interactive web apps with a Kotlin Armeria server backend. Using Ho

Starter project with PEKK stack.

Running the project To run the project, you need to run the server and the frontend. Running the server In the terminal, run ./gradlew narcore-server:

Android Note app that uses the "ktor-note-app" backend

KtorNoteApp Android Notes app that uses Ktor back end server Technologies employed: Kotlin MVVM Coroutines Custom REST API build with Ktor Responds to

Shoppe - Kotlin and Ktor app, which can easily be deployed to Heroku

[ 🚧 Work in progress 👷‍♀️ ⛏ 👷 🔧️ 👷 🔧 🚧 ] Shoppe Kotlin Multiplatform App

A small backend for the Thinkrchive app written in Kotlin with Ktor

A small backend for the Thinkrchive app written in Kotlin with Ktor. It uses Postgresql with a few requests and JWT authentication for admins.

The WeeBe application is a social media-type app built on Ktor framework

The WeeBe application is a social media-type app built on Ktor framework that allows users to exchange various content connected with mental health, motivation, psychology, and improving oneself. Users can share posts with texts, images, videos, and links, as well as discuss the content in the comment section

This is a sample app to demonstrate the power of using EventSourced models and the ease with which these can be modelled using Kotlin.
This is a sample app to demonstrate the power of using EventSourced models and the ease with which these can be modelled using Kotlin.

Lego 4 Rent This is a sample app to demonstrate the power of using EventSourced models and the ease with which these can be modelled using Kotlin. To

Owner
Sam
Bit of this, bit of that.
Sam
Utility library dedicated for functional & non-functional codebases to simplify modelling of success and failure responses for the JVM languages 🔀

Expressible Utility library, part of the panda-lang SDK, dedicated for functional codebases that require enhanced response handling. Express yourself

Panda 28 Nov 14, 2022
Integration Testing Kotlin Multiplatform Kata for Kotlin Developers. The main goal is to practice integration testing using Ktor and Ktor Client Mock

This kata is a Kotlin multiplatform version of the kata KataTODOApiClientKotlin of Karumi. We are here to practice integration testing using HTTP stub

Jorge Sánchez Fernández 29 Oct 3, 2022
KTor-Client---Android - The essence of KTor Client for network calls

KTor Client - Android This project encompasses the essence of KTor Client for ne

Mansoor Nisar 2 Jan 18, 2022
Showcase project of Functional Reactive Programming on Android, using RxJava.

FunctionalAndroidReference FunctionalAndroidReference is a showcase project of Functional Reactive Programming on Android, using RxJava. It's a compan

Paco 278 Nov 18, 2022
sample project that shows you how you can use Ktor to creat a server for real Project.

Ktor-Sample This is a sample project that shows you how you can use Ktor to creat a server for real Project. What is done Save data to database (Get a

Mohamed Emad 4 Dec 23, 2022
A sample to demonstrate how to use Compose with Ktor Websockets

This is a sample to demonstrate how to use Compose with Ktor Websockets

Ahmed Nabil 8 Dec 23, 2022
A functional, fractional-byte programming language

Fig A functional, fractional-byte programming language. Tired of annoying Unicode codepages in your favorite golfing languages? Fig uses pure, printab

null 10 Dec 15, 2022
sharex image uploader using ktor

ktor-sharex-uploader uploader zdjec napisany w kotlinie przy uzyciu ktor pobierak gotowa jarka jest do pobrania tutaj config apki konfiguracje apki ma

Michał 11 Jun 10, 2022
Backend coding challenge using Kotlin and Ktor

Backend Coding Challenge We appreciate you taking the time to participate and su

Thermondo 0 Jan 4, 2022
Multiplatform HTTP-Client implementation using Ktor

Kotlin Multiplatform HTTP-Client using Ktor Simple demonstration of a Ktor-based multiplatform HTTP-client in Kotlin Overview base submodule: common c

Jan Weidenhaupt 2 Oct 21, 2022