Backend is written in Kotlin and uses Javalin as its main HTTP server with a couple of extensions developed within Reposilite Playground organization. Main libraries used by project:
- Javalin - HTTP server based on Jetty
- Exposed - SQLite, MySQL DSL support
- AWS S3 Client - Remote file storage
- Expressible - Functional programming extensions, mostly used to work around
Result<Value, Error>
pattern - Picocli - Command line and command-like configuration properties support
- JUnit 5 - Unit & integration tests
- Testcontainers - Integration test, requires Docker (for Windows you need Docker Desktop). Don't worry if you're not able to run these tests locally - you can always make PR, and we'll run it through GitHub Actions automatically :)
- See build.gradle.kts for more
Since 3.x Reposilite supports multiple infrastructure targets, it's written using design patterns known as
Domain Driven Development (DDD) &
Hexagonal architecture used in business to guarantee high quality of code organized by a well-know structure.
What does it mean? Well, to simplify this aspect it mostly comes to the overall app layout and the way the code is organized.
That's why you can expect to see this kind of sources in reposilite-backend
module:
com.reposilite
feature/ # That's our domain, called 'feature'
api/ # Public API exposed by 'feature' domain
ResponseDto.kt # E.g. a DTO with a response returned by FeatureFacade
application/ # Application layer classes that somehow configures the given domain
FeaturePlugin.kt # Main configuration class used to register plugin-like domain in Reposilite app
infrastructure/ # Infrastructure dependent implementations
SQLRepository.kt # E.g. an implementation based on SQL
Repository.kt # Some abstract components to implement by various infrastructure impls
FeatureFacade.kt # Unified class that contains all public methods exposed by the given domain
When you're trying to add something to Reposilite, try to think about every domain as a standalone module and follow this pattern :) If you want to learn more about it, visit some great dedicated articles, like e.g. Organizing Layers Using Hexagonal Architecture, DDD, and Spring
You can run Reposilite in various ways, it depends on what you expect:
- Run classes that end with
*Test.kt
to launch simple unit tests without launching Reposilite - Run classes that end with
*InfrastructureTest.kt
to launch infrastructure tests that run Reposilite with required dependencies in Docker image - Run Reposilite in test workspace with predefined configuration for IntelliJ - Reposilite.run.xml
- Run all tests with Gradle -
gradlew test
- Build final fat JAR -
gradlew clean build shadowJar
- Build final fat JAR without tests -
gradlew -x test clean build shadowJar