# Migrate from OpenAPI Generator

Source: https://apigenie.pl/docs/guides/migrate-from-openapi-generator

This guide moves a repository that generates clients or servers with OpenAPI Generator to
`apigenie-generator`: the generator names, the options, the files you own, the build and the CI
step, and what has no counterpart. It starts from OpenAPI Generator 7.x, run as
`openapi-generator-cli`, from its Maven or Gradle plugin or from the npm wrapper, and an OpenAPI
file, `openapi.yaml`.

You need the CLI installed; the [Quickstart](/docs/quickstart) shows how. Keep OpenAPI Generator
until the last step: the two can generate into separate directories while you compare.

## What changes and what stays

| | OpenAPI Generator | API Genie |
| --- | --- | --- |
| Command | `openapi-generator-cli generate -g spring -i openapi.yaml -o server` | `apigenie-generator server spring openapi.yaml -o server` |
| Targets | 172 generators, in Java, Kotlin, Swift, Rust, PHP and more | 6 clients and 8 servers from OpenAPI, 14 targets from AsyncAPI, a documentation site, example data ([the list](/docs/reference/generator)) |
| Input | OpenAPI 2.0 and 3.x | OpenAPI 3.0 to 3.2; Swagger 2.0 through `apigenie convert`; AsyncAPI 3, GraphQL, Protobuf, JSON Schema |
| Options | `--additional-properties a=b,c=d`, `-c config.yaml` | `-p a=b -p c=d`, `commands.generate.<target>` of `apigenie.yaml` |
| Files you own | `.openapi-generator-ignore`, `--skip-overwrite` | the implementation files, written only when missing; `.openapi-generator-ignore` for Spring, Java and FastAPI |
| Changing the output | Mustache and Handlebars templates, `-t` | an [overlay](/docs/reference/generator#overlays) and the `x-apigenie` extensions, no templates |
| Checking the input | `--skip-validate-spec` to skip it | always; `apigenie lint` says what to fix |
| Runtime | Java 11 or later | a native binary: archives, `.deb`, `.rpm`, npm, Homebrew, Docker |
| Build plugins | Maven, Gradle | none; a step before the build, or generated code checked in and verified in CI |

## Run both on the same document

```sh
openapi-generator-cli generate -g typescript-fetch -i openapi.yaml -o client-oag
apigenie-generator client fetch openapi.yaml -o client --package-name shipping-client
```

The target comes first, as two words, and the input comes last; `-i` and `-g` are gone, `-o` stays.
The output is an npm package with no runtime dependency: requests go through the global `fetch()`,
and each operation is an `async` function named after its `operationId`, taking one object of
parameters, as `useSingleRequestParameter` gives in OpenAPI Generator.
[Generate a client and a server](/docs/guides/generate-a-client-and-a-server) shows the client in
use.

## The generators by name

| OpenAPI Generator | API Genie | Note |
| --- | --- | --- |
| `typescript-fetch`, `typescript-axios`, `typescript-node` | [client fetch](/docs/reference/generator/client-fetch) | one TypeScript client on the global `fetch()`, for browsers and Node.js 18 or later; `layout: sources` for a bundler |
| `java` | [client java](/docs/reference/generator/client-java) | `--library restclient` (default), `resttemplate`, `feign` or `http-interface`: the client depends on Spring Framework, not on OkHttp or Jersey |
| `spring` | [server spring](/docs/reference/generator/server-spring) | the same code and options, in place (below) |
| `python` | [client python](/docs/reference/generator/client-python) | httpx and Pydantic 2 |
| `python-fastapi` | [server fastapi](/docs/reference/generator/server-fastapi) | the same layout and options, in place (below) |
| `go` | [client go](/docs/reference/generator/client-go) | `net/http`; `layout: module` writes `go.mod` |
| `go-server`, `go-gin-server` | [server go](/docs/reference/generator/server-go) | `net/http` |
| `csharp` | [client csharp](/docs/reference/generator/client-csharp) | `HttpClient` with `IHttpClientFactory` registration; `target_framework: net8.0` to `net10.0` |
| `aspnetcore` | [server aspnet](/docs/reference/generator/server-aspnet) | Minimal APIs |
| `elixir` | [client elixir](/docs/reference/generator/client-elixir) | Req |
| `nodejs-express-server` | [server express](/docs/reference/generator/server-express) | TypeScript, typed handlers, requests validated with Ajv or generated validators |
| `html`, `html2`, `markdown`, `asciidoc`, `dynamic-html` | [docs](/docs/reference/generator/docs) | one site for several documents, with Try it out and search |
| `openapi`, `openapi-yaml` | [apigenie convert](/docs/reference/cli/convert), [apigenie bundle](/docs/reference/cli/bundle) and [apigenie format](/docs/reference/cli/format) | |
| `kotlin`, `swift6`, `rust`, `dart`, `php`, `ruby`, `scala-*`, `cpp-*`, `kotlin-spring`, `java-*` servers, `python-flask`, `rust-server`, ... | no counterpart | keep OpenAPI Generator for these targets; both can run in one repository |

The other commands: `openapi-generator-cli validate` is [apigenie lint](/docs/reference/cli/lint),
`list` is the help of `apigenie-generator`, which names the targets, `config-help -g` is the
Configuration section of the target's page, and `batch` is one `apigenie.yaml` with a section per
target and one command per target. `meta`, which starts a generator of your own, has no
counterpart.

## Option by option

| OpenAPI Generator | API Genie |
| --- | --- |
| `-i openapi.yaml` | the last argument |
| `-g NAME` | the target, `client fetch`, `server spring`, ... |
| `-o DIR` | `-o DIR` |
| `-c config.yaml` | `-c apigenie.yaml`, section `commands.generate.<target>` |
| `--additional-properties a=b,c=d` | `-p a=b -p c=d`, or the keys of that section |
| `--package-name`, `npmName`, `packageName` | `--package-name`: the npm package, the Python distribution, the Go package, the C# namespace, the Java base package, the Mix application |
| `--artifact-version`, `npmVersion`, `packageVersion` | `--package-version` |
| `--library` | `--library` of `client java`; `library` of `server spring` |
| `--invoker-package`, `--api-package`, `--model-package`, `--group-id`, `--artifact-id` | `basePackage`, `apiPackage`, `modelPackage`, `groupId`, `artifactId` of `client_java` and `server_spring` |
| `--type-mappings`, `--import-mappings` | `typeMappings` and `importMappings` (Java, Spring), `type_mappings` (Go) |
| `--model-name-prefix`, `--model-name-suffix` | `model_suffix` (C#, ASP.NET), `modelNamePrefix` (FastAPI) |
| `--global-property apis` or `models` | `include_tags` and `exclude_tags` (Go, Elixir, Phoenix), `generate: [types]` (`server go`) |
| `--inline-schema-name-mappings` | `class_overrides` (Python), `module_overrides` (Elixir, Phoenix) |
| `--openapi-normalizer` | an overlay, for the changes that fit one |
| `useTags` | `useTags` (Java, Spring), `grouping: tag` (C#, ASP.NET, Express), `group_by: tag` (Python) |
| `--skip-validate-spec`, `-t`, `--engine`, `--minimal-update`, `--dry-run`, `-s`, `--server-variables`, `--remove-operation-id-prefix`, `--git-*`, `--release-note`, `--http-user-agent`, `--enable-post-process-file` | no counterpart |

An option a target does not know is an error, not ignored, so a copied configuration says at once
what did not carry over.

## Keep your code out of the generated files

OpenAPI Generator protects your files with `.openapi-generator-ignore` and `--skip-overwrite`.
Each server target of `apigenie-generator` has a place for your code that regenerating never
touches:

- `server spring`: the controllers, written only when missing, or the delegates with
  `delegatePattern: true`; `.openapi-generator-ignore` is read.
- `server fastapi`: the `impl` package, the tests of the APIs and `tests/conftest.py`, written only
  when missing; `.openapi-generator-ignore` is read.
- `server express`: the handlers, in files of your own, that the generated router calls.
- `server aspnet`: `Program.cs` and the stub implementations, written only when missing.
- `server go`: your implementation of the generated interfaces, and `main.go` with `main: true`,
  written only when missing.
- `server phoenix`: your implementations of the generated behaviours.

`client java` writes `.openapi-generator-ignore` too. For the other targets, generate into a
directory of its own: everything in it is generated, and your code lives next to it.

## Regenerate a Spring or FastAPI project in place

`server spring` produces the code of OpenAPI Generator's `spring` generator and accepts the same
options; `server fastapi` has the layout and the options of `python-fastapi`. A project generated
by OpenAPI Generator is generated again by `apigenie-generator`, in the same directory, with the
same `.openapi-generator-ignore`. The `config.yaml` of OpenAPI Generator:

```yaml
basePackage: com.acme.pets
delegatePattern: true
useBeanValidation: true
```

goes under the target in `apigenie.yaml`, as it is or under an `additionalProperties` key:

```yaml
version: '1.0'
commands:
  generate:
    server_spring:
      basePackage: com.acme.pets
      delegatePattern: true
      useBeanValidation: true
```

```sh
apigenie-generator server spring openapi.yaml -o server
git diff --stat server
```

The differences each page lists under "Differences from openapi-generator" show up in that diff:
for Spring, `useSpringBoot3` is `true` by default and the files are marked
`@Generated(value = "API Genie")`; for FastAPI, routes declare their status code and response
class, the models are Pydantic 2 models without `to_dict()` and `from_dict()`, and `oneOf` is a
union. Both read OpenAPI 3.0 to 3.2 only: `apigenie convert --to openapi32` for a Swagger 2.0
document, `apigenie bundle` for one that references other files.

## The build and CI

The Maven plugin's `generate-sources` execution and the Gradle `openApiGenerate` task become a
command before the build, since `apigenie-generator` is a binary rather than a plugin: an
`exec-maven-plugin` execution, a Gradle `Exec` task, or an npm script with the CLI from the
`@mykulyak/api-genie` package, which pins its version in `package.json` as `openapitools.json`
did. In Docker, `mykulyak/apigenie` runs it with `--entrypoint apigenie-generator`.

Or generate into the repository and let CI check that the generated code matches the contract:

```sh
apigenie-generator client fetch openapi.yaml -o client --package-name shipping-client
apigenie-generator server spring openapi.yaml -o server
git diff --exit-code client server
```

The step fails when someone edited the generated code by hand or forgot to regenerate.

## What has no counterpart

- **The targets listed above as such.** Kotlin, Swift, Rust, Dart, PHP, Ruby, Scala and C++
  clients, and the servers other than Spring, FastAPI, Express, ASP.NET Core, Go and Phoenix.
- **Templates and custom generators.** `-t`, `--engine` and `meta`: the output changes through
  the options, an overlay and the `x-apigenie` extensions each target's page lists.
- **Maven and Gradle plugins**, replaced by a step before the build.
- **`--skip-validate-spec`.** A document the generator cannot use stops it with exit status 2.

## Remove OpenAPI Generator

When the generated projects build and their tests pass: remove `@openapitools/openapi-generator-cli`
and `openapitools.json`, or the plugin from `pom.xml` and `build.gradle`, delete the
`.openapi-generator/` directories and the `.openapi-generator-ignore` files of the targets that do
not read them, and replace the generation step in CI.
