Skip to content

Ktor Starterpack for real-world API development for Kotlin

Notifications You must be signed in to change notification settings

whipsterCZ/ktor-starterpack-dk

Repository files navigation

DK Ktor Starterpack for real-world API development for Kotlin

Production ready , and easy to use starterpack for Ktor API development. It has Sensible feature set which every large-scale (or quality) application should have.

The source code can also serve as learning material. It's build with personal know-how and experience collected during development in PHP + Laravel, Typescript + express, C# + Unity3D, Swift iOs Apps. and more..

It is designed with large-scale applications in mind.

I hope it helps you! Feel free leave feedback or your ideas (Code review appreciated).

Main focus:

  • Modern (y2023) - Kotlin & Ktor based, using kotlin advanced features
  • Best practices - Domain Driven Design, Clean Architecture, SOLID, KISS, YAGNI, DRY
  • Simplicity - Clarity, Obviousness, No-Magic, No-annotations, NO-unnecessary features,
  • Easy-to-use - (preconfigured, extendable, DI, config (support .env), logging, example REST included)
  • Modular Approach -
    • every module is self-contained (single folder) and can be used independently
    • Loose coupling
    • wn Routing, Dependency Injection, Services etc..
  • Production Ready
    • it is suited for small and large projects
    • Performance (Ktor, Kotlin, Coroutines, EventLoop)
    • Docker, Kubernetes, Helm, CI/CD, Monitoring, Logging, Metrics, etc..

Technology stack:

  • Kotlin
  • Ktor (framework)
  • Koin (DI library)
  • Logback (Logging configured for ELK (Kibana, Logstash))
  • dotenv .env
  • Swagger UI (exposed API Documentation )
  • JUnit5
  • Docker
  • Gradle
  • Prometheus
  • REST API

Design

alt Design model UML

Running

sh gradlew run

Running with auto-reload

!!! IMPORTANT !!! auto-reload feature - which broke singletons! @see stackOverflow

set .env file or ENV variable

ENVIRONMENT=development

Since Auto-reload detects changes in output files, we need to enable automatic project rebuilding. To do this, execute the following command in a repository's root directory:

sh gradlew -t build

Follow the steps below to see Auto-reload in action:

  1. Open another terminal tab and run a sample:
    sh gradlew run
  2. Open http://localhost:8080/ to see a sample text in a browser.
  3. Change a text passed to the respondText method in Application.kt and save a file.
  4. Refresh the http://localhost:8080/ page to see the updated text.

Configuration

see .env.sample file

Features

  • Ktor framework
  • Configuration using .env file
  • Dependency Injection Koin
    • should we use Eager initialization?
  • App structure (Modules)
  • Logging configure runtime
    • LoggerService
    • separated LoggerContext
    • Check if all logs are compatible with ELK
    • Scoped logger per request (meta data userId, shopId, etc) @see ReqContext.kt
    • MethodCalled meta
    • Request logging with correct scope and loggerName
  • Error Handling
    • Global handling of NotFoundException, RequestValidationException, BadRequestException, IllegalArgumentException, etc
  • Monitoring
  • serialization
  • Validation
    • Request & Internal & Response Validation
    • Custom solution - KTOR RequestValidationPlugin is just not good enough
    • Validation with nice error messages @see [ValidationException]
    • Extendable validation
  • Testing
    • Testing EP with snapshots
    • Example module test (ArticleModule)
  • Deployment
    • Docker
    • gitlab-ci
    • k8s
  • Example module (Articles)
    • Routing (Resource Controller)
    • Repository
    • Service
    • Model
    • ModelExporter (versioned JSON export)
    • Tests
    • Request & Response validation
    • RequestContext (contextual logger and metadata) @see plugins/RequestContext.kt
  • Root ApiInfo endpoint / (version, build, swagger, urls, etc)
  • Graceful shutdown
  • Swagger
    • serve swagger.yml /swagger/swagger.yml
    • swagger-ui /swagger

Known issues

  • Auto-reload feature - which broke singletons! KTOR-4842
    • if singleton is created inside Application module, it will be created only once (on first request) and KtorAutoLoader should don't release instance
    • in development mode, it is not problem i guess... (only Singleton which is created outside of module is Config...)
  • CallLogging sets custom logger (app.router) - but it is used by KTOR system logging...
  • Serializer for LogLevel doesn't work @see /lib/serializers/LogLevelSerializer.kt"
  • Metrics are in default second units (prometheus default) - im was unable to change it to milliseconds
  • Resource param validation weirdness (KTOR)
    • if http://0.0.0.0:3000/v1/articles?status=NEEXISTUJE
    • first time i have correct 400 BadRequest: cz.danielkouba.ktorStarterpackDk.modules.article.model.ArticleStatus does not contain element with name 'PUBLISHEDs'
    • second time i have wierd 400 BadRequest: io.ktor.server.plugins.BadRequestException: Can't transform call to resource
    • solvable with custom validation (don't use any Enums as types)
  ____     __  __        __  __     ______   ______     ______
/\  __-.  /\ \/ /       /\ \/ /    /\__  _\ /\  __ \   /\  == \
\ \ \/\ \ \ \  _"-.     \ \  _"-.  \/_/\ \/ \ \ \/\ \  \ \  __<
 \ \____-  \ \_\ \_\     \ \_\ \_\    \ \_\  \ \_____\  \ \_\ \_\
  \/____/   \/_/\/_/      \/_/\/_/     \/_/   \/_____/   \/_/ /_/
    GINGER BEAVERS          STARTERPACK FOR KOTLIN KTOR SERVERS 

About

Ktor Starterpack for real-world API development for Kotlin

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published