Repository navigation
Releases: mykulyak/api-genie
Release list
API Genie CLI 0.9.0
Highlights
- Translations for all five standards.
apigenie i18n extractandi18n applywork on OpenAPI, Swagger 2.0,
AsyncAPI, Protobuf and GraphQL files: the texts are extracted keyed by JSON pointers, declaration names or schema
coordinates, and translations are put back without touching the rest of the file
(i18n). - Contract testing across OpenAPI, Swagger, AsyncAPI, gRPC and GraphQL, with TLS.
apigenie testruns.http
files (HTTP, gRPC, WebSocket, MQTT and GraphQL requests) and generated requests against a live API, and
apigenie-mock --proxy-tosits between clients and a real server or broker (HTTP, WebSocket, MQTT, gRPC, GraphQL),
checking every request and response against the contract. Both report coverage, JSON and JUnit reports, and fail
CI with--fail-onand--min-coverage. TLS is supported throughout: the mock serves HTTPS, WSS and gRPC over TLS
(--tls-cert,--tls-key), and requests and upstreams can behttps://,wss://andmqtts://, verified against
the system's CA certificates (--ca-cert,--insecure) (test,
mock server). - Code generation for five stacks. Clients and servers for TypeScript (fetch, Express, oRPC, WebSocket, Kafka on
KafkaJS, Zod), Python (httpx, FastAPI, FastStream), Go (net/http, Kafka), Java (Spring clients and servers, Kafka)
and C# (HttpClient, ASP.NET Core, Kafka), from OpenAPI 3.0–3.2 and, for event-driven APIs, AsyncAPI 3.x. Every target
is checked by a conformance suite: snapshots, the target's own compiler and linter, and a run against
apigenie-mock --proxy-to. The generators are a separate executable,apigenie-generator, installed with the CLI
(apigenie-generator). - Web components for every spec type, and
generate docs. Theapg-*custom elements
(@mykulyak/apigenie-web-componentson npm) document OpenAPI, Swagger 2.0, AsyncAPI, Protobuf/gRPC and GraphQL
APIs, with Try it out for HTTP and GraphQL, built on the same engine as the CLI compiled to WebAssembly.
apigenie-generator docscompiles any of these files, several at once, into a docs bundle that the components
render into a static site (npm install && npm run build), with translations, the git changelog and example
files; it replacesgenerate doc html(see Upgrading).
Upgrading
apigenie generateis nowapigenie-generator. The code generators moved out ofapigenieinto a separate
executable,apigenie-generator, installed next to it by every archive and package, the npm package and Homebrew,
and included in themykulyak/apigenieDocker image (docker run --entrypoint apigenie-generator ...). Drop
generatefrom the command line:apigenie generate client fetch spec.yaml -o outbecomes
apigenie-generator client fetch spec.yaml -o out. The options and thecommands.generatesection of the
configuration file are unchanged;apigenie generatefails as an unknown command. The banners of generated files
name the new command. The entries below still call the generatorsgenerate <target>. The design is ADR-123.generate doc htmlis replaced bygenerate docs, with no alias.apigenie-generator docs openapi.yaml -o docs
replacesapigenie generate doc html openapi.yaml --output docs; it takes several inputs of mixed families (OpenAPI,
Swagger 2.0, AsyncAPI, GraphQL, Protobuf) and makes one site, and-c/--config,--i18n LOCALE=FILE,
--package-nameand--package-versionkeep their meaning. The output is no longer an Astro project but a docs
bundle (apigenie-docs.jsonanddocuments/<id>/document.<locale>.json, ADR-122) with apackage.jsonthat
depends on@mykulyak/apigenie-web-componentsinstead of@mykulyak/api-genie-doc-html-template;
npm install && npm run buildstill builds the static site, now intodist/, prerendered from the web components.
--bundle-onlywrites the bundle alone, for a site built by other means. The CLI does not run Node. The
configuration sectioncommands.generate.doc_htmliscommands.generate.docs:html_title_prefixistitle,
i18n.default_localeandi18n.prefix_default_localemove to the top of the section (the locales come from
--i18n),changelogkeeps its name (also--changelog), anddocumentslists the inputs (file,id,
title,proto_paths,examples).pages,operations,resources,search,sidebar,html_meta,
template,openapi_schema,request_code_examples,use_request_body_examples,generate_response_schema,
use_response_examplesandfail_on_generator_errordescribed the Astro layout and have no replacement: the site
has the layout of<apg-api-reference>(navigation with search, one page per operation and schema), themed with
the components' CSS custom properties and::part(). Generated Astro projects keep building with the template they
depend on, but nothing regenerates them: rungenerate docsinto a new directory.- New dependency: Mbed TLS.
apigenieandapigenie-mocklink Mbed TLS 3.6 (Apache-2.0) forhttps://,
wss://andmqtts://connections; release binaries grow by about 0.9 MB. Builds from source get it from vcpkg
(mbedtls >= 3.6.2). Verifying servers needs the system's CA certificates: the Docker images now include them; in
your own minimal images installca-certificates.apigenie creditsandapigenie license --library mbedtlslist
it. - Telemetry is opt-in. The CLI no longer writes
.apigenie.telemetryin the current directory, and sends
nothing. SetAPIGENIE_TELEMETRY_FILEto a path to keep a local telemetry log; old.apigenie.telemetryfiles
can be deleted. i18nhas subcommands.apigenie i18n FILE --output DESTbecomesapigenie i18n extract FILE --output DEST.lintfails on errors.lintexits with status 1 when issues of severityerrorremain (after--fix), so CI
jobs that ran it only for its report fail now; lower the severities in the configuration to keep them passing.apigenie-mock --stubswith a GraphQL schema or an AsyncAPI document exits with status 2 instead of ignoring
the option.
Added
generate docsdocuments OpenAPI, Swagger 2.0, AsyncAPI, GraphQL and Protobuf files, several at once, as one static
site: it writes a docs bundle (apigenie-docs.json; per document and locale the resolved document, or the
documentation model of AsyncAPI, GraphQL and Protobuf files; with--changelogthe git changelog, asapigenie changelogcomputes it; the example files next to a GraphQL schema and those listed in the configuration) and the
npm project that renders it with@mykulyak/apigenie-web-components(npm install && npm run build): prerendered
pages with declarative shadow DOM that hydrate in the browser, Try it out, a sitemap, a locale switcher for the
--i18nlocales, a changelog page and the examples.--bundle-onlywrites the bundle alone. Internal: the
docs_bundlelibrary (compileDocsBundle),changelog_helpers(the changelog of any family, shared with the
changelogcommand), andgraphql_describeandprotobuf_describe, which write the documentation models that the
graphqlandprotobufWebAssembly modules used to write themselves, asasyncapi_describedoes for AsyncAPI.
The design is ADR-122.generate server spring(OpenAPI) routes QUERY operations andadditionalOperationssuch as COPY: their handlers
carry@ExtensionMethod("QUERY"), which the generatedExtensionMethodConfigurationmatches through a custom
request condition of the request mapping (WebMvcRegistrations, orWebFluxRegistrationswithreactive=true).
pipeDelimitedandspaceDelimitedarray query parameters are split on their separator (@DelimitedParameter),
and query parameters with JSONcontentare read as JSON into their model (@JsonParameter), which is null and
left unvalidated when the parameter is absent; both converters are registered byParameterConversionConfiguration.
Request media types whose bodies have different types get a handler each, named as the methods of
generate client java(updateShipmentforapplication/merge-patch+json,updateShipmentWithJsonPatchfor the
application/json-patch+jsonarray). The newApiExceptionHandleranswers invalid requests with a 400 Problem
(type,title,status,detailand, for constraint violations of the parameters,errorswith thename,
pathandmessageof each), where aConstraintViolationExceptionused to answer 500. Conformance Level 3 of the
target only expects the x-internal operation, which servers leave out, to fail.generate server aspnet(OpenAPI) falls back to the default mapping of a discriminator (defaultMapping, or
x-defaultMappingbefore 3.2): unions are read and written by the converters ofgenerate client csharp, written
next to the abstract record and attached with[JsonConverter]instead of[JsonPolymorphic], so a missing or
unmapped discriminator reads as the default type, and the discriminator may be anywhere in the object on .NET 8 too.
Request media types whose bodies have different types get an endpoint and API method each, named as the methods of
the C# client (UpdateShipmentforapplication/merge-patch+json,UpdateShipmentJsonPatchfor the
application/json-patch+jsonarray) and restricted to their media types withAccepts<T>(), so routing picks the
endpoint by Content-Type; the JSON Patch array used to be bound as aShipmentPatchobject (400). Conformance Level 3
of the target passes with only the x-internal operation, which the server leaves out, expected to fail.- The codegen conformance runner decides that the x...
API Genie CLI 0.10.0
The mock server is now apigenie-server, with a document store for CRUD resources and several services in one
process, and a fourth binary, apigenie-catalog, keeps a repository's API catalog. apigenie-generator applies
OpenAPI overlays before generating, and the three binaries share one table of exit statuses.
Highlights
apigenie-server, the mock server and validating proxy under its new name, with a dashboard at
/__apigenie/ui(Traffic, Operations, Scenarios, Contract, Data and, for AsyncAPI, Channels), several services on
one port with a prefix each, a document store (ctx.db,db.crud: autoresources, seeding, snapshots), session
recording and replay (--record DIR,--replay DIR), client certificates, MQTT 5 properties, and validating
proxies for Kafka (--proxy-to kafka://) and AMQP (--proxy-to amqp://) brokers.apigenie-catalog(experimental), a fourth binary:catalog listfinds the API specifications of a
repository andcatalog initrecords them inapigenie.yaml.- Code generation:
--overlay FILEon every OpenAPI and AsyncAPI target; the Elixir family (client elixirand
server phoenixfor OpenAPI and AsyncAPI,server absinthefor GraphQL,server elixir-grpcand the Elixir gRPC
client for Protobuf);server mcp(experimental), a Model Context Protocol server from an OpenAPI document;
server orpcat the conformance bar. apigenie testspeaks Kafka and AMQP (KAFKAandAMQPregions), GraphQL subscriptions over graphql-ws,
gRPC client and bidirectional streams, MQTT 5 and mutual TLS.- Towards 1.0: one table of exit statuses for the binaries,
formatVersionin every JSON report with published
JSON Schemas, a JSON Schema forapigenie.yamlbehindapigenie config,config checkandconfig schema,
configuration discovery without--config, the Compatibility page, and experimental labels on what is outside
the coming promise. - Linting and diffing: the OpenAPI format registry as the list of formats, with
schema-format-deprecated,
schema-format-unknownand ahintseverity;diffknows sunset dates and no longer rates deprecating as
breaking;apigenie evolve plan OLD NEW(experimental) plans an expand/contract migration. - Also:
convert --from wsdl --to openapi31,i18n checkandi18n sync, OpenAPI formatting at every depth with
layout options, Windows console colors, and a docs package published as@mykulyak/apigenie-docs.
Upgrading
-
Upgrading from 0.9:
apigenie-mockis nowapigenie-server. The mock server and validating proxy is
installed asapigenie-serverby every archive and package, the npm package and Homebrew, and its Docker image is
mykulyak/apigenie-server. The old names keep working until 1.1, each with a one-line deprecation notice on
standard error:apigenie-mockis a symlink toapigenie-server(a copy in the Windows archive, a command of the
npm package), and theAPIGENIE_MOCK_*variables are read when theAPIGENIE_SERVER_*variable of the same name
is unset. The lastmykulyak/apigenie-mockimage (latestand this version) only prints the new name and exits
with 2; older tags are unchanged.apigenie-server.yamlis read beforeapigenie-mock.yaml, which still works;
commands.mock, thex-apigenie-mockextensions, theX-Apigenie-Mock-*headers and the/__apigenieadmin API
are unchanged. What the server sends saysapigenie-serverinstead: theServerandViaheaders, the HAR
creator, the admin statusname, theBasicrealm, the MQTT client ids, and the contract report'sreport
member (apigenie-server-contract) and JUnit suite name (apigenie-server contract). The reference page moved to
server; the old address redirects. The design is ADR-147. -
One table of exit statuses for
apigenie,apigenie-generatorandapigenie-server. 0 success, 1 findings
(lint errors, breaking changes,format --checkdifferences,i18n apply --strictunknown keys,overlay --validateproblems), 2 a usage, input or unexpected error, 3 and 4apigenie-server's document and address
errors, 5 a failed contract report (apigenie-server,apigenie test). The 1.0 compatibility promise freezes it.
Scripts that check for the old numbers need these changes:- errors that exited with 255 (
-1) now exit with 2: unreadable or invalid input files inbundle,convert,
changelog,diff,i18n,lintandoverlay, bad configurations, and every error ofapigenie-generator; - errors that exited with 1 now exit with 2: unknown options and commands, missing files, configuration files that
can't be parsed,formaton a file with syntax errors or an unsupported document,bundleof a.protofile
with errors,license --librarywith an unknown name, and unexpected errors inapigenie-serverandapigenie test; apigenie testexits with 2 instead of 3 when a request file, an environment file or the specification can't be
read or parsed;apigenieandapigenie-generatorwithout a command, or with an unknown one, exit with 2 (255 before) and
print the help of the command above it on the standard error.
apigenie-serverkeeps 3, 4, 5 and 130. The design is ADR-141
(exit status). - errors that exited with 255 (
-
--versionlists the binaries installed next to it.apigenie --versionprints the version on its first line,
thenapigenie-generator VERSIONandapigenie-server VERSIONfor those found in the same directory (the same for
the other two binaries). Scripts comparing the version should read the first line:apigenie --version | head -n 1. The GitHub Action, the Homebrew formula and the release workflows do. Subcommands no longer have a--version
of their own (apigenie lint --versionprinted 1.0). -
lint --formatter jsonanddiff --report detailed --formatter jsonwrite an object. Lint JSON is
{ "formatVersion": 1, "results": [...] }and the detailed diff report{ "formatVersion": 1, "changes": [...] };
both were bare arrays. Read.resultsand.changesinstead
(compatibility). -
diffno longer rates deprecating as breaking. In therecommendedrules, setting or clearingdeprecatedon an
operation, a parameter, a header or a schema isnon_breaking: it announces a removal, and the removal is the
breaking change (rated bysunset_passed, see Added). Gates that relied on it should setoperation.deprecated: breaking(andparameter,header,schema) incommands.diff.rules. The design is ADR-172. -
Seeded faker values change. Faker now draws its values with algorithms of its own, the same on every platform, and
name,emailand other values of a--seeddiffer from 0.9.0's. Usernames and emails are ASCII (Cieślarbecomes
Cieslar), anddate.betweenis a range ({date.between: {from: 2024-01-01, to: 2024-12-31}}) rather than an alias of
date.recent. -
Faker arguments are checked.
x-faker,@mock(faker:, args:),graphql.fieldsandfake()reject arguments a
provider doesn't take, of the wrong type or out of bounds (a negative length, a probability above 1) with faker's
message, where they were clamped or ignored. -
apigenie formatkeeps the format of OpenAPI, Swagger and AsyncAPI files without a configuration. Formatting
api.jsonwith no--configused to writeapi.yamlnext to it; JSON files now stay JSON. Setformat: yamlto
convert them. -
The OpenAPI format configuration is checked. Unknown keys (
indnet), unknown objects inproperty_order,
indents outside 2 to 9 and unknown output formats are reported with their line and column, and nothing is
formatted; they used to be ignored or to abort the command. -
The
recommendedOpenAPI preset changes more of a document. It now reaches nested schemas, inline callbacks
and the objects of OpenAPI 3.2, sorts the path templates ofpaths(itspaths: sortedhad no effect), orders
more schema keywords ($ref,$id,$defs,default,examples,readOnly,writeOnly,deprecated...) and
the fields of 3.2 objects, and orders Reference Objects byreference. Expect a one-time diff when reformatting
withextends: [recommended].property_order.responsesapplies to the status codes of operations; the names of
components.responsesfollow the newcomponentNameskey. -
The configuration file is validated against a JSON Schema when it is loaded, by
apigenie,
apigenie-generatorandapigenie-server. Settings that were silently ignored are now errors (exit status 2) with
the line, the column and the JSON pointer of the value: unknown keys undercommands.*(the OpenAPI, AsyncAPI and
Swagger linters, and the WebSocket generators, used to skip them), sections of commands that have no settings
(commands.bundle,commands.changelog:changelogusescommands.diff), and values of the wrong type.
apigenie config checklists the errors of a file; fix them, or remove the settings that did nothing. The design is
ADR-145. -
apigenieandapigenie-generatorfind the configuration file without--config:apigenie.yaml(.yml,
.json, or.apigenie.*) in the current directory or a parent up to the root of the git repository. Pass
--no-configto run with the defaults, as before, in a repository that has such a file.apigenie-serverfalls
back to the same file after its ownapigenie-server.yamlandapigenie-mock.yaml. -
The docs package is
@mykulyak/apigenie-docs. The npm project thatapigenie-generator docswrites now
depends on@mykulyak/apigenie-docs(^0.1.0), the new name of the web components package. 0.9.0 wrote
@mykulyak/apigenie-web-componentsinto ...
v0.8.2-alpha
Full Changelog: cli-0.8.0...cli-0.8.2
v0.8.0-alpha
Full Changelog: https://github.com/mykulyak/api-genie/commits/cli-0.8.0