{"id":20471514,"url":"https://github.com/backbase/openapi-with-quarkus","last_synced_at":"2026-03-19T16:02:21.677Z","repository":{"id":235490412,"uuid":"787835528","full_name":"Backbase/openapi-with-quarkus","owner":"Backbase","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-13T15:13:05.000Z","size":211,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-20T20:02:51.684Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Backbase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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,"publiccode":null,"codemeta":null}},"created_at":"2024-04-17T09:18:23.000Z","updated_at":"2025-08-13T15:13:09.000Z","dependencies_parsed_at":"2025-03-05T13:42:54.115Z","dependency_job_id":"9d858966-7a8d-4947-ac57-1f933419c6f7","html_url":"https://github.com/Backbase/openapi-with-quarkus","commit_stats":null,"previous_names":["backbase/openapi-with-quarkus"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Backbase/openapi-with-quarkus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fopenapi-with-quarkus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fopenapi-with-quarkus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fopenapi-with-quarkus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fopenapi-with-quarkus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Backbase","download_url":"https://codeload.github.com/Backbase/openapi-with-quarkus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fopenapi-with-quarkus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30240904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T00:58:18.660Z","status":"ssl_error","status_checked_at":"2026-03-08T00:55:48.608Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-11-15T14:16:23.671Z","updated_at":"2026-03-19T16:02:21.671Z","avatar_url":"https://github.com/Backbase.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenApi Generator Usage on Sample Quarkus Application\n\nThis example covers the approach adopted on an Identity project when generating API clients with Resteasy for\n**Identity Service Provider Interfaces** which they are using Quarkus native libraries.\n\nFor **Spring**, with the help of the **boat-plugin**, we have the default configuration to use open-api-generator with\nSpring. It's already documented and is well known in Backbase.\n\nAlso, multi-tenancy (while creating api-client) and aspects of tracing will be covered with the examples.\n\n\u003e **_NOTE:_** Please take a look at\n\u003e the [BOAT Golden Example](https://github.com/Backbase/project-golden-samples/tree/main/boat)\n\u003e to understand how to use boat-plugin.\n\nFor **Quarkus**, to use openapi-generator the plugin must be configured.\n\n## Configuration of OpenApiGenerator Plugin\n\nThe input spec of this sample application can be\nfound [here](https://raw.githubusercontent.com/redhat-appdev-practice/todo-api/trunk/openapi.yml).\n\n```xml\n\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.openapitools\u003c/groupId\u003e\n    \u003cartifactId\u003eopenapi-generator-maven-plugin\u003c/artifactId\u003e\n    \u003cexecutions\u003e\n        \u003cexecution\u003e\n            \u003cid\u003etodo-api\u003c/id\u003e\n            \u003cgoals\u003e\n                \u003cgoal\u003egenerate\u003c/goal\u003e\n            \u003c/goals\u003e\n            \u003cconfiguration\u003e\n                \u003cinputSpec\u003e${project.basedir}/src/main/resources/todo.yaml\u003c/inputSpec\u003e\n                \u003cconfigOptions\u003e\n                    \u003cmodelPackage\u003eorg.quarkus.openapi.todo.model\u003c/modelPackage\u003e\n                    \u003capiPackage\u003eorg.quarkus.openapi.todo.api\u003c/apiPackage\u003e\n                \u003c/configOptions\u003e\n            \u003c/configuration\u003e\n        \u003c/execution\u003e\n    \u003c/executions\u003e\n    \u003cconfiguration\u003e\n        \u003coutput\u003e${codegen.openapi.generated-sources-dir}\u003c/output\u003e\n        \u003cgeneratorName\u003ejava\u003c/generatorName\u003e\n        \u003cgenerateApiTests\u003efalse\u003c/generateApiTests\u003e\n        \u003cgenerateModelTests\u003efalse\u003c/generateModelTests\u003e\n        \u003cgenerateModelDocumentation\u003efalse\u003c/generateModelDocumentation\u003e\n        \u003cgenerateApiDocumentation\u003efalse\u003c/generateApiDocumentation\u003e\n        \u003cconfigOptions\u003e\n            \u003clibrary\u003eresteasy\u003c/library\u003e\n            \u003cdateLibrary\u003ejava8\u003c/dateLibrary\u003e\n            \u003copenApiNullable\u003efalse\u003c/openApiNullable\u003e\n            \u003cinvokerPackage\u003eorg.quarkus.openapi.todo.api\u003c/invokerPackage\u003e\n            \u003cuseJakartaEe\u003etrue\u003c/useJakartaEe\u003e\n        \u003c/configOptions\u003e\n    \u003c/configuration\u003e\n\u003c/plugin\u003e\n```\n\n```\u003clibrary\u003eresteasy\u003c/library\u003e```\n\nThe resteasy library is used to generate resteasy client.\n\n```\u003cdateLibrary\u003ejava8\u003c/dateLibrary\u003e```\n\nJava8 date library is used.\n\n```\u003copenApiNullable\u003efalse\u003c/openApiNullable\u003e```\n\nOpenAPI Jackson Nullable library is disabled.\n\n```\u003cinvokerPackage\u003eorg.quarkus.openapi.todo.api\u003c/invokerPackage\u003e```\n\nRoot package for generated code\n\n## Config Class for API(s)\nWe have TodoApiConfig class, by using this config class, the API(s) usage is/are can be easy. At this example, we only have one API,\n\nif we would have multiple API's, the new API Clients would be created in the **TodoApiConfigFactory** class and would be ready to use by any service calling the **TodosApiConfig**.\n\nIn **TodoApiConfig** class, we are simply adding the generated TodosApi.\n\n***TodoApiConfig***\n```java\npublic class TodoApiConfig {\n    private final TodosApi todosApi;\n\n    public TodoApiConfig(TodosApi todosApi) {\n        this.todosApi = todosApi;\n    }\n\n    public TodosApi getTodosApi() {\n        return todosApi;\n    }\n}\n```\n\nIn **TodoApiConfigFactory** class, we have simply one method for creating **TodoApiConfig** which **TodosApi** will be created for the Config class.\n\n***TodoApiConfigFactory***\n\n```java\npublic class TodoApiConfigFactory {\n\n    /**\n     * Create Todo Api Config without tenant data.\n     *\n     * @return {@link TodoApiConfig}\n     */\n    public static TodoApiConfig createTodoApiConfig() {\n        return createTodoApiConfig(null);\n    }\n\n    /**\n     * Create Todo Api Config for a given tenant.\n     * Global scope is used to get base url.\n     *\n     * @return {@link TodoApiConfig}\n     */\n    public static TodoApiConfig createTodoApiConfig(Tenant tenant) {\n        Config.Scope scope = ConfigUtils.getGlobalScope();\n\n        Optional\u003cString\u003e tenantId = Optional.ofNullable(tenant).map(Tenant::getId);\n\n        TodosApi todosApi =\n            createTodoApi(tenantId.orElse(null), scope.get(TODO_API_BASE_URL_KEY));\n\n        if (Objects.isNull(todosApi)) {\n            log.error(\"Can't initialize Todos api for tenant: {}\", tenantId.orElse(\"\u003cno tenant\u003e\"));\n            return null;\n        }\n\n        return new TodoApiConfig(todosApi);\n    }\n\n    private static TodosApi createTodoApi(String tenantId, String baseUrl) {\n        if (Objects.isNull(baseUrl)) {\n            log.error(\"TodoApi base url is null\");\n            return null;\n        }\n\n        return new TodosApi(ApiClientFactory.createTenantApiClient(tenantId, baseUrl));\n    }\n```\n\n## Tracing\nAfter upgrading Quarkus dependencies, the tracing implementation has been simplified. The previous OpenTracing integration has been removed in favor of a more streamlined approach.\n\nAs a first step, we need to create **ApiClient** with the base path. We are using **JAXRS Default Client Builder** to create **JAXRS** Client.\n\nIf any logger is defined for debugging in ApiClient class, the logger class will be registered while creating **JAXRS** Client.\nLast step is setting the HttpClient. An HttpClient can be used to send requests and retrieve their responses. An HttpClient is created through a builder.\n\n(Since we are going to create a new **JAX-RS - Client**, we used **JAX-RS - Client Builder**)\n\n```java\n    /**\n     * Getting ApiClient configured for given tenant.\n     *\n     * @param basePath url path to given resource\n     * @return {@link ApiClient}\n     */\n    public static ApiClient createTraceApiClient(String basePath) {\n        ApiClient apiClient = new ApiClient().setBasePath(basePath);\n        ClientBuilder clientBuilder = ClientBuilder.newBuilder()\n            .register(apiClient.getJSON());\n\n        if (LoggerFactory.getLogger(ApiClient.class).isDebugEnabled()) {\n            clientBuilder.register(Logger.class);\n        }\n\n        return apiClient.setHttpClient(clientBuilder.build());\n    }\n```\n\n## Multi-tenancy\n\nEach time an API request is performed, we need to know to tenant identifier to correctly route the persistence\noperations.\n\nThere are around three most common ways to provide tenant identifier.\n\n1. Providing the tenant identifier as a **URL Part**\n2. Using a custom **HTTP Request header**\n3. Using JWTs to provide the tenant identifier as a JSON token claim\n\nFor this sample-app, second option through a custom HTTP header called **'X-TID'** is used.\n\n\n```java\n    public class ApiClientFactory {\n\n    private ApiClientFactory() {\n    }\n\n    /**\n     * Getting ApiClient configured for given tenant.\n     *\n     * @param basePath url path to given resource\n     * @return {@link ApiClient}\n     */\n    public static ApiClient createTraceApiClient(String basePath) {\n        ApiClient apiClient = new ApiClient().setBasePath(basePath);\n        ClientBuilder clientBuilder = ClientBuilder.newBuilder()\n            .register(apiClient.getJSON());\n\n        if (LoggerFactory.getLogger(ApiClient.class).isDebugEnabled()) {\n            clientBuilder.register(Logger.class);\n        }\n\n        return apiClient.setHttpClient(clientBuilder.build());\n    }\n\n    /**\n     * Getting ApiClient configured for given tenant (or without tenant if tenantId is null).\n     *\n     * @param tenantId id of given tenant\n     * @param basePath url path to given resource\n     * @return {@link ApiClient}\n     */\n    public static ApiClient createTenantApiClient(String tenantId, String basePath) {\n        ApiClient apiClient = createTraceApiClient(basePath);\n        if (Objects.isNull(tenantId)) {\n            return apiClient;\n        }\n\n        return apiClient.addDefaultHeader(\"X-TID\", tenantId);\n    }\n}\n```\n\nAfter the trace api client is created, the custom **HTTP request header** (**X-TID**) is added.\n\n## Tests\nWe have basic tests for Factory classes, TodoApiConfig and Provider class to ensure that our ApiClient and ApiConfig are initialized correctly.\n\n**TodoApiConfigTest**\n```java\n   @ExtendWith(MockitoExtension.class)\n    class TodoApiConfigTest {\n\n    @Mock\n    private TodosApi todosApi;\n\n    @InjectMocks\n    private TodoApiConfig todoApiConfig;\n\n    @Test\n    void shouldReturnAllApis() {\n        assertNotNull(todoApiConfig.getTodosApi());\n    }\n}\n```\nFor factory class tests: there are different methods to verify the **ApiClient** is created correctly. \n\nDetailed test can be found (creating **ApiConfig** with the tenant/without tenant) on [TodoApiConfigFactoryTest](src/test/java/org/quarkus/openapi/generator/config/TodoApiConfigFactoryTest.java) class.\n\n## Running the application in dev mode\n\nYou can run your application in dev mode that enables live coding using:\n\n```shell script\n./mvnw compile quarkus:dev\n```\n\n\u003e **_NOTE:_**  Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.\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\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\n\nYou can create a native executable using:\n\n```shell script\n./mvnw package -Pnative\n```\n\nOr, if you don't have GraalVM installed, you can run the native executable build in a container using:\n\n```shell script\n./mvnw package -Pnative -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\nIf you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.\n\n## Provided Code\n\n### RESTEasy Reactive\n\nEasily start your Reactive RESTful Web Services\n\n[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbackbase%2Fopenapi-with-quarkus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbackbase%2Fopenapi-with-quarkus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbackbase%2Fopenapi-with-quarkus/lists"}