Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interactive Playground #348

Merged
merged 20 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/deploy-playground-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
##
## Worklow for deploying the playground application to Fly.io
##
name: Deploy Playground (Production)
on:
push:
branches:
- master
workflow_dispatch: {}

jobs:
deploy:
name: Deploy to Fly.io
runs-on: ubuntu-latest
concurrency: deploy-group # ensure only one action runs at a time
steps:
- uses: actions/checkout@v4
- uses: superfly/flyctl-actions/setup-flyctl@master
- name: Build jar
run: ./gradlew :playground:shadowJar
- name: Deploy
run: cd playground && flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Fabrikt `/ˈfa-brikt/` - Kotlin code from OpenAPI 3

---

* [Introduction](#introduction)
* [Features](#features)
* [Examples](#examples)
Expand All @@ -12,12 +10,11 @@
* [Maven](#maven)
* [Getting the Most from Fabrikt](#getting-the-most-from-fabrikt)
* [Configuration Options](#configuration-options)
* [Original Motivation](#original-motivation)
* [Building Locally](#building-locally)
* [Publishing](#publishing)
* [Specific Features](#specific-features)

---

## Introduction

This library was built to take advantage of the complex modeling features available in OpenAPI 3. It generates Kotlin data classes with advanced support for features such as:
Expand All @@ -33,13 +30,15 @@ This library was built to take advantage of the complex modeling features availa

as well as HTTP clients and controllers for a number of popular frameworks (see [Features](#features)).

More than just bootstrapping, this library can be permanently integrated into a gradle or maven build and will ensure contract and code always match, even as APIs evolve in complexity.
More than just bootstrapping, this library can be permanently integrated into your build tool and will ensure contract and code always match, even as APIs evolve in complexity.

### Try Fabrikt Online

The team that built this tool initially contributed to the Kotlin code generation ability in [OpenApiTools](https://github.com/OpenAPITools/openapi-generator), but reached the limits of what could be achieved with template-based generation. This library leverages the rich OpenAPI 3 model provided by [KaiZen-OpenApi-Parser](https://github.com/RepreZen/KaiZen-OpenApi-Parser) and uses [Kotlin Poet](https://square.github.io/kotlinpoet/) to programmatically construct Kotlin classes for maximum flexibility.
Try Fabrikt with your own API spec and see how it can help you generate code for your API clients and servers.

It was built at [Zalando Tech](https://opensource.zalando.com/) and is battle-tested in production there. It is particularly well-suited to API's built according to Zalando's [REST API guidelines](https://opensource.zalando.com/restful-api-guidelines/).
[Fabrikt Playground](https://fabrikt.fly.dev)

The library is [available on Maven Central](https://search.maven.org/artifact/com.cjbooms/fabrikt) at the following coordinates:
### Coordinates

```xml
<dependency>
Expand Down Expand Up @@ -245,6 +244,16 @@ This section documents the available CLI parameters for controlling what gets ge
| | `JAKARTA_VALIDATION` - Use `jakarta.validation` annotations in generated model classes |
| | `NO_VALIDATION` - Use no validation annotations in generated model classes |

## Original Motivation

The team that built the first version of this tool initially contributed to the Kotlin code generation ability in
[OpenApiTools](https://github.com/OpenAPITools/openapi-generator), but reached the limits of what could be achieved with
template-based generation. This library leverages the rich OpenAPI 3 model provided by
[KaiZen-OpenApi-Parser](https://github.com/RepreZen/KaiZen-OpenApi-Parser) and uses [Kotlin Poet](https://square.github.io/kotlinpoet/) to
programmatically construct Kotlin classes for maximum flexibility.

The initial version was built at [Zalando Tech](https://opensource.zalando.com/) and is battle-tested in production there

## Building Locally

Fabrikt is built with Gradle and requires an initialised git repository. The easiest way to build it is to clone the repo locally before executing the build command:
Expand Down
7 changes: 7 additions & 0 deletions playground/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM openjdk:17-jdk-slim

WORKDIR /app

COPY build/libs/playground-all.jar /app/playground-all.jar

CMD ["java", "-jar", "playground-all.jar"]
34 changes: 34 additions & 0 deletions playground/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Fabrikt Playground

The Fabrikt Playground is a web based tools that allows you to play around with
Fabrikt without installing it locally.

The goal is to make lower the barrier for trying out Fabrikt and to hopefully prove to
people that Fabrikt can be a useful tool for the user and encourage them to embed it in
their development workflow either via the CLI or via Gradle/Maven.

## Technical Details

The playground is built with these amazing Open Source libraries ♥️
* [Ktor](https://github.com/ktorio/ktor) for HTTP
* [kotlinx.html](https://github.com/Kotlin/kotlinx.html) for HTML without writing HTML
* [htmx](https://github.com/bigskysoftware/htmx) for interactivity
* [PrismJS](https://github.com/PrismJS/prism) for syntax highlighting
* [Ace Editor](https://github.com/ajaxorg/ace) for YAML editing
* [Normalize.css](https://github.com/necolas/normalize.css) for default styling
* [BassCSS](https://basscss.com/) for utility CSS

## Building and Deploying

1. Build the jar
```shell
gradle :playground:shadowJar
```

2. Build the Docker image

```shell
docker build -t fabrikt-playground .
```

3. Deploy to the PaaS of choice :rocket:
96 changes: 96 additions & 0 deletions playground/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
plugins {
application
kotlin("jvm")
id("com.github.johnrengelman.shadow") version "8.1.1"
id("com.palantir.git-version") version "3.0.0"
}

application {
mainClass.set("PlaygroundApplicationKt")
applicationDefaultJvmArgs = listOf("-Dio.ktor.development=true")
}

repositories {
mavenCentral()
}

val ktorVersion: String by rootProject.extra

dependencies {
implementation(project(":"))

// ktor server
implementation("io.ktor:ktor-server-netty-jvm:$ktorVersion")
implementation("io.ktor:ktor-server-content-negotiation-jvm:$ktorVersion")
implementation("io.ktor:ktor-server-html-builder:$ktorVersion")
implementation("io.ktor:ktor-server-call-logging:$ktorVersion")

// logging
implementation("ch.qos.logback:logback-classic:1.5.6")

implementation("com.squareup:kotlinpoet:1.14.2") { exclude(module = "kotlin-stdlib-jre7") }

testImplementation(kotlin("test"))
}

tasks.test {
useJUnitPlatform()
dependsOn("shadowJar")
}

kotlin {
jvmToolchain(17)
}

tasks.withType<Jar> {
manifest {
attributes["Main-Class"] = "PlaygroundApplicationKt"
}
}

tasks.withType<CreateStartScripts> {
dependsOn(tasks.shadowJar)
}

tasks.named("shadowJar") {
dependsOn(":shadowJar")
}

val gitVersion: groovy.lang.Closure<*> by extra
version = gitVersion.call()

val generatedDir = layout.buildDirectory.dir("generated/version")

tasks.register("generateVersionFile") {
val versionCode = gitVersion.call().toString()
val outputDir = generatedDir.get().asFile
inputs.property("gitVersion", versionCode)
outputs.dir(outputDir)
doLast {
val file = outputDir.resolve("Version.kt")
file.parentFile.mkdirs()
file.writeText(
"""
object Version {
const val GIT_VERSION = "$versionCode"
}
""".trimIndent()
)
}
}

sourceSets {
main {
java.srcDir(generatedDir)
}
}

tasks.named("compileKotlin") {
dependsOn("generateVersionFile")
}

tasks.named("shadowJar", com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class) {
archiveBaseName.set("playground")
archiveClassifier.set("all")
archiveVersion.set("")
}
22 changes: 22 additions & 0 deletions playground/fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# fly.toml app configuration file generated for fabrikt on 2025-01-10T13:45:20+01:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'fabrikt' # --> https://fabrikt.fly.dev
primary_region = 'ams'

[build]

[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = 'suspend'
auto_start_machines = true
min_machines_running = 0
processes = ['app']

[[vm]]
memory = '512mb'
cpu_kind = 'shared'
cpus = 1
Loading
Loading