{"id":15013838,"url":"https://github.com/carlosedp/scala3-quarkus-quickstart","last_synced_at":"2025-04-12T05:46:49.719Z","repository":{"id":213428176,"uuid":"734096381","full_name":"carlosedp/scala3-quarkus-quickstart","owner":"carlosedp","description":"A Sample Scala 3 / Quarkus application with Kafka, persistence and tests.","archived":false,"fork":false,"pushed_at":"2025-04-10T10:56:46.000Z","size":772,"stargazers_count":34,"open_issues_count":2,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-12T05:46:26.197Z","etag":null,"topics":["quarkus","scala","scala3"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/carlosedp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-12-20T21:26:40.000Z","updated_at":"2025-04-10T10:56:40.000Z","dependencies_parsed_at":"2023-12-21T00:55:15.474Z","dependency_job_id":"164157cf-6295-404f-996a-1939dcdf8e58","html_url":"https://github.com/carlosedp/scala3-quarkus-quickstart","commit_stats":null,"previous_names":["carlosedp/scala3-quarkus-quickstart"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carlosedp%2Fscala3-quarkus-quickstart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carlosedp%2Fscala3-quarkus-quickstart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carlosedp%2Fscala3-quarkus-quickstart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carlosedp%2Fscala3-quarkus-quickstart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/carlosedp","download_url":"https://codeload.github.com/carlosedp/scala3-quarkus-quickstart/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248525154,"owners_count":21118616,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["quarkus","scala","scala3"],"created_at":"2024-09-24T19:44:50.603Z","updated_at":"2025-04-12T05:46:49.684Z","avatar_url":"https://github.com/carlosedp.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# scala3-quarkus-quickstart \u003c!-- omit in toc --\u003e\n\n[![Maven CI](https://github.com/carlosedp/scala3-quarkus-quickstart/actions/workflows/Maven-CI.yaml/badge.svg)](https://github.com/carlosedp/scala3-quarkus-quickstart/actions/workflows/Maven-CI.yaml)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=carlosedp_scala3-quarkus-quickstart\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=carlosedp_scala3-quarkus-quickstart)\n[![codecov](https://codecov.io/gh/carlosedp/scala3-quarkus-quickstart/graph/badge.svg?token=IlH0MwK3RA)](https://codecov.io/gh/carlosedp/scala3-quarkus-quickstart)\n\nThis project is a quickstart using Scala 3 and Quarkus, the Supersonic Subatomic Java Framework.\n\nIf you want to learn more about Quarkus, please visit its website: \u003chttps://quarkus.io/\u003e.\n\nTo learn more about Scala and new in [Scala 3](https://docs.scala-lang.org/scala3/book/introduction.html), check-out \u003chttps://docs.scala-lang.org/scala3/new-in-scala3.html\u003e.\n\n## Development tools recommendation \u003c!-- omit in toc --\u003e\n\nTo start developing in Quarkus/Scala 3, I recommend the following tools:\n\n- [Coursier](https://get-coursier.io/) to manage Scala tools and JVM install\n- GraalVM 21 installed thru Coursier\n- Install scalafmt and scalafix thru Coursier\n- [Quarkus CLI](https://quarkus.io/get-started/)\n- [VSCode](https://code.visualstudio.com/) as IDE\n- The following VSCode Extensions\n  - [Metals](https://marketplace.visualstudio.com/items?itemName=scalameta.metals) by ScalaMeta\n  - [Scala Syntax](https://marketplace.visualstudio.com/items?itemName=scala-lang.scala)\n  - [Scaladex search](https://marketplace.visualstudio.com/items?itemName=baccata.scaladex-search)\n  - [Quarkus Tools](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-quarkus)\n\nThis repository demonstrates multiple Quarkus concepts and provides tooling, such as:\n\n- Running automated tests with [Github Actions](https://github.com/carlosedp/scala3-quarkus-quickstart/actions/workflows/CI.yaml) on PRs and pushes\n- Maven and Gradle build tools, configured and provided as a choice to the user\n- Application [Config](https://quarkus.io/guides/config) as in [GreetingResource.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/blob/main/src/main/scala/org/acme/GreetingResource.scala)\n- Apache [Kafka](https://quarkus.io/guides/kafka) as in [ArticleProducerConsumer.scala/ArticleProcessor.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/tree/main/src/main/scala/org/acme/kafka)\n- Database Persistence using [Scala Magnum](https://github.com/AugustNagro/magnum) as in [persistence/magnum](https://github.com/carlosedp/scala3-quarkus-quickstart/tree/main/src/main/scala/org/acme/persistence/magnum)\n- Database Persistence using [Hibernate](https://quarkus.io/guides/hibernate-orm) as in [persistence/hibernate](https://github.com/carlosedp/scala3-quarkus-quickstart/tree/main/src/main/scala/org/acme/persistence/hibernate)\n- Using Serialization with support for Scala types and Enums as in [Scala3ObjectMapperCustomizerTest.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/tree/main/src/test/scala/org/acme/Scala3ObjectMapperCustomizerTest.scala)\n- Using [Qute templates](https://quarkus.io/guides/qu$$te) as in [UserResource.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/tree/main/src/main/scala/org/acme/persistence/magnum/UserResource.scala)\n- Use of [rest-assured](https://github.com/rest-assured/rest-assured) with a [Scala 3 wrapper](https://github.com/carlosedp/scala3-quarkus-quickstart/blob/main/src/test/scala/helper/RestAssuredHelper.scala) for testing REST as in [RestAssuredHelperTest.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/blob/main/src/test/scala/helper/RestAssuredHelperTest.scala)\n- Application [startup and shutdown customization](https://quarkus.io/guides/lifecycle) as in [Main.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/blob/main/src/main/scala/org/acme/Main.scala)\n- Application [Metrics](https://quarkus.io/guides/smallrye-metrics) for Prometheus as in [GreetingResource.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/blob/21a6bf51007210d2ae5d6a8bb96ff36b6c88c9a6/src/main/scala/org/acme/GreetingResource.scala#L17) and [ArticleProcessor.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/blob/21a6bf51007210d2ae5d6a8bb96ff36b6c88c9a6/src/main/scala/org/acme/kafka/ArticleProcessor.scala#L15-L16)\n- Scala Futures as in [GreetingResource.scala](https://github.com/carlosedp/scala3-quarkus-quickstart/blob/main/src/main/scala/org/acme/GreetingResource.scala#L52) with async method calls using Scala sttp library.\n- Docker-compose configuration providing the full stack of requirements for the demos (Kafka, database, Metrics, etc)\n\n## Table of Contents \u003c!-- omit in toc --\u003e\n\n- [Running the application in dev mode](#running-the-application-in-dev-mode)\n- [Application Examples](#application-examples)\n  - [Simple greet app](#simple-greet-app)\n  - [Kafka Producer -\\\u003e Processor -\\\u003e Consumer](#kafka-producer---processor---consumer)\n  - [Database Persistence](#database-persistence)\n  - [Using Scala Futures and Zio](#using-scala-futures-and-zio)\n  - [Using the full stack as a \"production\" application](#using-the-full-stack-as-a-production-application)\n- [Running Tests](#running-tests)\n- [Packaging and running the application](#packaging-and-running-the-application)\n- [Creating a native executable and container](#creating-a-native-executable-and-container)\n- [Tooling UI](#tooling-ui)\n- [Command Matrix](#command-matrix)\n- [Build Tool Usage](#build-tool-usage)\n- [Customizing provided code](#customizing-provided-code)\n\n\n## Running the application in dev mode\n\nRun your application in dev mode that enables live coding using:\n\n```shell script\n./mvnw compile quarkus:dev #or\n./gradlew --console=plain quarkusDev\n# or using the quarkus-cli (https://quarkus.io/get-started/)\nquarkus dev\n```\n\n\u003e **_NOTE:_**  Quarkus now ships with a Dev UI, which is available in dev mode only at \u003chttp://localhost:8080/q/dev/\u003e.\n\u003e On dev mode and production mode, the Swagger UI can be opened at \u003chttp://localhost:8080/swagger-ui\u003e.\n\nThis sample project contains multiple small \"applications\" that uses different libraries to show it's usage.\n\nOpen \u003chttp://localhost:8080\u003e that shows Quarkus static demo page. It shows the endpoints that are exposed.\n\nIf running the application standalone (for example with native binary), start the Docker-compose stack with `docker-compose up -d` so all requirements are run like Kafka, Kafka-UI for management, Postgres and PGAdmin. Also user and database are created automatically.\n\n## Application Examples\n\nBelow there are descriptions for some of the concepts demonstrated in this sample app.\n\n### Simple greet app\n\nThe endpoints \u003chttp://localhost:8080/hello\u003e or \u003chttp://localhost:8080/greet?name=Yourname\u003e are written in Scala provided by the [GreetingResource.scala](./src/main/scala/org/acme/GreetingResource.scala) source file. Based on input, it returns a text text.\n\n### Kafka Producer -\u003e Processor -\u003e Consumer\n\nThis sample app uses Kafka as a messaging middleware passing data between a Producer, a Consumer and a Processor. There is an HTML interface at \u003chttp://localhost:8080/articles.html\u003e to interact with the application. The built-in Kafka UI can be seen at \u003chttp://localhost:8080/q/dev-ui/io.quarkus.quarkus-kafka-client/topics\u003e.\n\nThe example uses Scala native `case class`es, `Enum`s and uses Jackson for serialization of these objects for processing using Kafka topics. It also generates metrics for amount of messages processed and processing time.\n\nIn this example, I force the \"mismatch\" of channel names in the `application.properties` config (matching names and Kafka topics) to make sure the SmallRye lib doesn't use in-memory queues instead of Kafka itself for message passing as a fallback (\u003chttps://quarkus.io/guides/kafka#in-memory-channels\u003e).\n\n![article submission sample](./docs/articles.png)\n\n### Database Persistence\n\nThe persistence examples include JPA with Hibernate ORM, and the new kid on the Scala 3 block, [Magnum](https://github.com/AugustNagro/magnum).\nFollowing the Magnum example you can easily also integrate Anorm, Slick or Doobie. Doobie is a bit more complex as you will have to bridge Cats Effect IO to CompletionStage/CompletableFuture. If you feel adventurous you can try bridging with SmallRye Mutiny Uni, which is lazy by default and more close in behaviour to Cats Effect IO.\n\nThe sample using **Scala 3 Magnum** lib lives under \u003chttp://localhost:8080/users/users-page\u003e. Data is stored into Quarkus dev Postgres database that is started in dev mode.\n\n![users](./docs/users.png)\n\nAnother sample using **hibernate** which is really un-Scala like, but it's there for reference. Some other Quarkus integrations might expect JPA to be present so there it is.\n\nTo view the sample, open \u003chttp://localhost:8080/tasks/tasks-page\u003e and interact with the form.\n\n### Using Scala Futures and Zio\n\nYou can also interop Scala `Future`s with Quarkus as it's used on multiple Scala native async libraries. If using `Await.result` inside a method (which blocks the thread which it was called from), annotate it with `@Blocking` (from `io.smallrye.common.annotation.Blocking`) to make Quarkus move the method to a separate thread pool meant for blocking operations. Otherwise (as is demonstrated on `ScalaFutureResource.scala`) return a `CompletionStage` which can be obtained from Scala Future by using `scala.jdk.FutureConverters`. This is used in the \u003chttp://localhost:8080/async/future\u003e endpoint.\n\nThere is also a resource that executes and returns data from a Zio Effect. The example code is at `ScalaZioResource.scala` and it uses some helper method and extension from `ZioHelper.scala` for ease of use. The effect is run and it's return is converted to a native Java `CompletionStage` for Quarkus consumption.\n\n### Using the full stack as a \"production\" application\n\nThe application can be built as a complete production application, in it's own Container image and executed using a `docker-compose` that contains all the application's dependencies (PostgreSQL, Kafka, Prometheus and all UIs for these tools). The Docker Composer file also builds the container image for the application in JVM mode. If desired to use the app in Native Image mode, build the image as instructed [here](#creating-a-native-executable-and-container) and use it's name in the `docker-compose.yml` file `image:` tag and comment the `build:` section to avoid building the JVM based image.\n\n## Running Tests\n\nTo run tests, use:\n\n```sh\n# using quarkus-cli which will run in continuous testing\nquarkus test\n# or using Maven/Gradle\n./mvnw -B verify\n./gradlew test\n```\n\nQuakus tooling runs all requirements like the database, Kafka broker, etc on containers using a locally installed Docker or Podman.\n\n## Packaging and running the application\n\nThe application can be packaged using:\n\n```shell script\n./mvnw package\n```\n\nIt produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory.\nBe aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.\n\nThe application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.\n\nRunning docker-compose (or podman-compose), builds the image using the `./src/main/docker/Dockerfile.openj9` Dockerfile and the application as a `jar`. Editing the `docker-compose-yml` file you can change the default JVM base container.\n\nIf you want to build an _über-jar_, execute the following command:\n\n```shell script\n./mvnw package -Dquarkus.package.type=uber-jar\n```\n\nThe application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.\n\n## Creating a native executable and container\n\nYou can create a native executable using:\n\n```shell script\n./mvnw package -Dnative\n```\n\nOr, if you don't have GraalVM installed, you can build the native executable in a container using:\n\n```shell script\n./mvnw package -Dnative -Dquarkus.native.container-build=true\n```\n\nYou can then execute your native executable with: `./target/code-with-quarkus-1.0.0-SNAPSHOT-runner`\n\nTo build the container image with the Native Image application, use:\n\n```sh\nquarkus build --native --no-tests -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true -Dquarkus.native.builder-image=graalvm\n# or\n./mvnw package -Dnative -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true\n# or\n./gradlew build -Dquarkus.native.enabled=true -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true -Dquarkus.native.builder-image=graalvm\n```\n\nSome libraries (specially those not from Quarkus distribution) might require run-time initialization config in `quarkus.native.additional-build-args` inside `application.properties`. As an example, `scala.util.Random` required this to be able to build the GraalVM native image. To identify this behavior, GraalVM outputs an error as shown [here](https://github.com/scalameta/sbt-native-image/issues/27).\n\nIf you want to learn more about building native executables, please consult \u003chttps://quarkus.io/guides/maven-tooling\u003e and \u003chttps://quarkus.io/guides/building-native-image#creating-a-container\u003e.\n\n## Tooling UI\n\nThe following URLs can be used to manage the deployed tools by Quarkus or Docker-Compose stack (when used):\n\n- App Homepage - \u003chttp://localhost:8080/\u003e\n- Swagger UI - \u003chttp://localhost:8080/swagger-ui\u003e\n- Quarkus Dev UI (only in dev mode) - \u003chttp://localhost:8080/q/dev-ui\u003e\n- Kafka UI (using docker-compose) - \u003chttp://localhost:9021\u003e\n- PGadmin (Postgres admin interface) (using docker-compose) - \u003chttp://localhost:8088\u003e\n- Prometheus collecting application and JVM metrics (using docker-compose) - \u003chttp://localhost:9090\u003e\n\n## Command Matrix\n\nBelow are the most used commands for development/test/package for each build tool:\n\n| Task                      | Quarkus Command                                                | Maven Command                                                   | Gradle Command                                                                        |\n| ------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------- |\n| Dev Mode                  | `quarkus dev`                                                  | `./mvnw quarkus:dev`                                            | `./gradlew quarkusDev`                                                                |\n| List Extensions           | `quarkus extension`                                            | `./mvnw quarkus:list-extensions`                                | `./gradlew listExtensions`                                                            |\n| Add Extension             | `quarkus extension add smallrye-*`                             | `./mvnw quarkus:add-extension -Dextensions='smallrye-*'`        | `./gradlew addExtension --extensions='smallrye-*'`                                    |\n| Run Tests                 | `quarkus test`                                                 | `./mvnw -B verify`                                              | `./gradlew test`                                                                      |\n| Download deps offline     |                                                                | `./mvnw quarkus:go-offline`                                     | `./gradlew quarkusGoOffline`                                                          |\n| Package Jar               | `quarkus build`                                                | `./mvnw install`                                                | `./gradlew build`                                                                     |\n| Uber Jar                  | `quarkus build -Dquarkus.package.type=uber-jar`                | `./mvnw package -Dquarkus.package.type=uber-jar`                | `./gradlew build -Dquarkus.package.type=uber-jar`                                     |\n| Native Binary             | `quarkus build --native`                                       | `./mvnw package -Dnative`                                       | `./gradlew build -Dquarkus.package.type=native`                                       |\n| Native Bin (in container) | `quarkus build --native -Dquarkus.native.container-build=true` | `./mvnw package -Dnative -Dquarkus.native.container-build=true` | `./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true` |\n\nScala lint tools like ScalaFmt and ScalaFix can be run using the lint goal/task in Maven and Gradle as:\n\n```sh\n./mvnw -Plint\n#or\n./gradlew lint\n```\n\nRefs:\n\n- \u003chttps://quarkus.io/guides/maven-tooling\u003e\n- \u003chttps://quarkus.io/guides/gradle-tooling\u003e\n\n## Build Tool Usage\n\nThe project contains build config for both Maven and Gradle.\n\nYou can choose your tool and remove the files related to the build tool not in use:\n\nMaven files: `.mvn mvnw mvnw.bat pom.xml`\nGradle files: `.gradle gradlew gradlew.bat build.gradle settings.gradle`\n\n## Customizing provided code\n\nTo reuse this code as a template for your own applications, remember to change the following:\n\n- For code analisys, create accounts on [Sonarcloud](https://sonarcloud.io) and [Codecov](https://app.codecov.io/) if desired\n- For Action automations, create an account on [Mergify](https://dashboard.mergify.com/) if desired and configure the actions on `.mergify.yml`\n- Update readme pointing to your own Sonarcloud (if kept), Codecov and GitHub action badges\n- The codebase is very independent from each other so one could remove Kafka, Database, Greet without breaking the other functionality\n- For databases, if using Hibernate, you can remove Scala 3 Magnum dependencies, if using Magnum, can remove Hibernate. All dependencies are commented in `pom.xml` or `build.gradle`\n- If Sonarcloud is not needed, change:\n  - Remove the GitHub action (./github/workflows/CI.yaml) cache task and update the test task removing additional sonar mvn tasks\n  - Remove `sonar` properties from pom.xml\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarlosedp%2Fscala3-quarkus-quickstart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarlosedp%2Fscala3-quarkus-quickstart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarlosedp%2Fscala3-quarkus-quickstart/lists"}