All jobs

Generate a Typed API Client for a Spring Boot Service

Yes. An agent boots the customer's Spring Boot service, exports its OpenAPI with springdoc, generates a TypeScript client and runs it against the server.

Run this on RushIn a Project that has your repository.

What the agent does

The agent first works out how the service builds and runs. In a Spring Boot app like spring-projects/spring-petclinic, pom.xml inherits spring-boot-starter-parent 4.1.0, sets <java.version>17</java.version> (and the maven-enforcer-plugin refuses an older JVM), and pulls in spring-boot-starter-webmvc, spring-boot-starter-data-jpa, spring-boot-starter-thymeleaf, spring-boot-starter-actuator, H2, MySQL and Postgres drivers. application.properties sets database=h2, loading db/h2/schema.sql and db/h2/data.sql at startup, so the default profile needs no external database, and management.endpoints.web.exposure.include=* exposes every actuator endpoint. The agent installs a Java 17 or newer JDK and starts the app with ./mvnw spring-boot:run, the Maven wrapper the repository ships.

Then it looks for the OpenAPI document and, in this repository, finds there is none: no springdoc-openapi dependency in pom.xml or build.gradle. The prompt allows for that. The agent adds a springdoc-openapi-starter-webmvc-ui release that supports the project's Spring Boot version to the sandbox copy of pom.xml only, sets springdoc.show-actuator=true on the command line so actuator endpoints are included, restarts, and fetches /v3/api-docs. It never commits or pushes that change; the report says it was made and why, so the customer knows the document came from their running code plus one added library.

The document shows what kind of API this is, and the agent says so. PetClinic is a server-rendered Thymeleaf app: OwnerController, PetController and VisitController return view names for HTML pages and form posts, and only VetController.showResourcesVetList, mapped to GET /vets with @ResponseBody, returns JSON, a Vets object whose list serializes as vetList. The agent generates a TypeScript client for every operation with openapi-typescript and openapi-fetch, compiles it with tsc --noEmit, and writes endpoints.md sorting the operations into JSON endpoints a client can use as data and HTML endpoints that return a page as a string.

For the smoke test it writes smoke.ts, which calls three read endpoints through the generated client against the running server: GET /vets, GET /actuator/health and GET /owners/{ownerId} for an owner the H2 seed data creates. The first two return JSON the client types; the third returns HTML, and the script prints its status and content type to show how the client handles it. The output goes to smoke-output.txt.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Start this Spring Boot service in the sandbox with its Maven wrapper and the JDK its pom.xml requires. If it serves no OpenAPI document, add springdoc-openapi-starter-webmvc-ui in a version that supports this Spring Boot release to the sandbox copy of pom.xml only, start it with springdoc.show-actuator=true, and fetch /v3/api-docs; never commit or push that change. Save the document as openapi.json. Generate a typed TypeScript client for every endpoint with openapi-typescript and openapi-fetch, and compile it with tsc --noEmit. Write endpoints.md listing each operation as JSON or HTML by its response content type. Write smoke.ts that calls three read endpoints through the client against the running server, printing status, content type and body, and save its output as smoke-output.txt. Return client.zip, openapi.json, endpoints.md, smoke.ts and smoke-output.txt as files.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

The session's artifacts are the five files, each downloadable from its url on api.prix.dev without a key for an hour: client.zip with the generated schema.d.ts types and a small typed openapi-fetch wrapper, openapi.json as /v3/api-docs served it, endpoints.md, smoke.ts and smoke-output.txt. The agent's final answer, the session's result and the webhook's data.result, states whether springdoc had to be added, whether the client compiled and what each smoke call returned.

endpoints.md decides what you deliver. For an API-first service most operations are JSON and the client is ready to publish. For a server-rendered app like this one, a customer who wants a client for their data learns that only GET /vets and the actuator endpoints return JSON, which is a finding worth showing them before anyone builds on it. Check that smoke-output.txt shows real JSON from /vets and /actuator/health before shipping the package.

Run it on every tagged release of the customer's service

When a customer tags a release, start a session with https://github.com/<owner>/<repo>/tree/<tag> in resources and an Idempotency-Key made from the repository and tag. Each tag gets its own sandbox and its own build, so the client you publish matches the code at that tag rather than whatever was on the default branch when the job ran.

The run.completed webhook tells your backend when the files are ready. Download client.zip before its link expires (reading the session again returns a fresh one), publish it under the customer's release version, and keep openapi.json beside it so the next generation can be compared against this one.

The use case this job follows, with its automation and trigger: Run an agent per customer task.

Why run it on Rush?

Building a Spring Boot service takes a JDK, a Maven download of the whole dependency tree and a running JVM, and generating a real document may mean adding springdoc to a build the customer owns. In a Rush sandbox the agent does that on a disposable copy: the added dependency, the build output and the running server exist only there, and nothing reaches the customer's repository unless you ask for it in a separate request.

The client is checked against the running service, not just generated. The compile, the three calls and their responses are kept in the session with every command the agent ran, so the package you hand over comes with the evidence that it talks to the server. Generations for many customers' services can run at the same time, each in its own sandbox.

Frequently asked questions

My service has no OpenAPI document. Will this still work?

Yes. The prompt tells the agent to add springdoc-openapi to the sandbox copy of pom.xml when the service serves no document, then fetch /v3/api-docs from the running app. The change is never committed; the result says it was made so the customer can add it themselves.

What happens with endpoints that return HTML pages?

They are in the document and the client, typed as returning a string, and endpoints.md marks them as HTML. A Thymeleaf controller that returns a view name is a page, not data, and the report makes that clear rather than presenting it as an API.

Does it need a real database?

Only if the default profile does. PetClinic's application.properties uses H2 with seed data, so nothing else is needed. For a service whose default profile needs Postgres or MySQL, the agent starts that database in the sandbox from the settings the app reads.

Does it work with Gradle builds?

Yes. The agent uses the build the repository defines, ./gradlew bootRun for Gradle and ./mvnw spring-boot:run for Maven, and adds springdoc to build.gradle or pom.xml accordingly, again only in the sandbox.