Spec4j makes your REST APIs YAMLless

enismustafaj1 pts1 comments

spec4j · Actions · GitHub Marketplace · GitHub

Skip to content

Search/

Sign in<br>Sign upAppearance settings

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

spec4j<br>Actions

About

Compile TypeSpec API contracts to a Spring Boot interface/DTO jar and publish it to a Maven registry<br>1.0.3<br>Latest

By enismustafaj

Star0 (0)You must be signed in to star a repositoryUse latest version<br>Choose a version

Tags<br>1 (1)<br>api-management

About

spec4j is a GitHub Action that turns a TypeSpec API contract into a versioned Java library: it compiles the .tsp file to OpenAPI, generates Spring Boot REST interfaces and DTOs from it, packages them as a Maven jar, and deploys that jar to a Maven registry.

The idea: define an API's shape once, in one contract repo, and let every service that implements or calls it depend on the generated library instead of hand-writing (and drifting from) its own interfaces.

Repo layout this action expects

A specs repo with one folder per API domain, each holding a main.tsp:

your-specs-repo/<br>├── users/main.tsp<br>├── orders/main.tsp<br>└── .github/workflows/<br>├── validate.yaml # compiles changed specs on PRs, publishes nothing<br>└── publish.yaml # calls this action on a release tag

See examples/users and examples/departments in this repo for sample main.tsp files, and .github/workflows/create-lib.yaml / publish.yaml for the reference workflows to copy into your repo.

Usage

> "$GITHUB_OUTPUT"<br>echo "version=${GITHUB_REF_NAME#*/v}" >> "$GITHUB_OUTPUT"<br>- uses: enismustafaj/spec4j@1.0.3<br>with:<br>spec-path: ${{ steps.release.outputs.domain }}/main.tsp<br>version: ${{ steps.release.outputs.version }}<br>registry-id: gitlab-maven<br>registry-url: https://gitlab.com/api/v4/projects//packages/maven<br>registry-token: ${{ secrets.GITLAB_TOKEN }}"># .github/workflows/publish.yaml<br>on:<br>push:<br>tags: ['*/v*'] # e.g. "users/v1.2.0"

jobs:<br>publish:<br>runs-on: ubuntu-latest<br>steps:<br>- uses: actions/checkout@v4<br>- id: release<br>run: |<br>echo "domain=${GITHUB_REF_NAME%%/*}" >> "$GITHUB_OUTPUT"<br>echo "version=${GITHUB_REF_NAME#*/v}" >> "$GITHUB_OUTPUT"<br>- uses: enismustafaj/spec4j@1.0.3<br>with:<br>spec-path: ${{ steps.release.outputs.domain }}/main.tsp<br>version: ${{ steps.release.outputs.version }}<br>registry-id: gitlab-maven<br>registry-url: https://gitlab.com/api/v4/projects//packages/maven<br>registry-token: ${{ secrets.GITLAB_TOKEN }}

For GitLab, use the numeric project ID in registry-url, not the namespace%2Fproject URL-encoded path. Both work with plain curl, but Maven's HTTP client mishandles the encoded slash and GitLab rejects the resulting request with a 400. Find the numeric ID on the project's main page or Settings → General .

Cutting a release is then just a tag:

git tag users/v1.2.0<br>git push origin users/v1.2.0

That publishes com.spec4j:users:1.2.0 (or whatever group-id/artifact-id you set) to the registry. There's no floating SNAPSHOT — a version only gets published when it's tagged, and version must be a plain X.Y.Z semver string.

Inputs

Input<br>Required<br>Default<br>Description

spec-path<br>yes<br>Path to the .tsp file to compile

version<br>yes<br>Version to publish, e.g. 1.2.0

registry-id<br>yes<br>Maven id (must match the registry's auth config)

registry-url<br>yes<br>Maven repository URL to deploy to

registry-token<br>yes<br>Registry auth token, sent as a Private-Token header

group-id<br>no<br>com.spec4j<br>Maven groupId for the generated package

artifact-id<br>no<br>spec's parent folder name<br>Maven artifactId

java-version<br>no<br>21<br>JDK version used to compile/deploy

Under the hood the action installs the TypeSpec compiler, runs tsp compile, renders template/pom-template.xml with these inputs, and runs mvn deploy using the bundled settings.xml (which reads the token from the registry-token input).

Local development

This repo includes a devcontainer spec (Node 22, Java 21, Maven) if you want to hack on the action itself without installing those locally.

Potential Improvements

Multi-language codegen targets (TypeScript/Python clients), not just Spring

AsyncAPI spec support

Breaking-change detection between spec versions

Contribution

In case you would like to contribute, please raise an issue and a PR for that issue.

Contributors1 (1)

Resources

Open an issue0 (0)<br>Pull requests0 (0)<br>View source code<br>Report abuse

spec4j is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.

About

Compile TypeSpec API contracts to a Spring Boot interface/DTO jar and publish it to a Maven registry<br>1.0.3<br>Latest

By enismustafaj

Tags<br>1 (1)<br>api-management

Contributors1 (1)

Resources

Open an issue0 (0)<br>Pull requests0 (0)<br>View source code<br>Report abuse

spec4j is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support...

registry maven version spec4j github publish

Related Articles