Server Framework Support
Typo generates server interfaces with framework-native annotations. Each framework gets idiomatic code that integrates naturally.
Java + JAX-RS
Full Jakarta EE/JAX-RS support with proper annotations:
@Path("/pets")
public interface PetsApiServer extends PetsApi {
/** Create a pet */
@Override
Response201400<Pet, Error> createPet(PetCreate body);
/** Endpoint wrapper - handles response status codes */
@POST
@Path("")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@SecurityRequirement(name = "oauth2", scopes = {"write:pets"})
default Response createPetEndpoint(PetCreate body) {
return switch (createPet(body)) {
case Created r -> Response.status(201).entity(r.value()).build();
case BadRequest r -> Response.status(400).entity(r.value()).build();
default -> throw new IllegalStateException("Unexpected response type");
};
}
@DELETE
@Path("/{petId}")
Void deletePet(@PathParam("petId") PetId petId);
}
Java + Spring Boot
Spring MVC with @RestController and response entities:
@RestController
@RequestMapping("/pets")
public interface PetsApiServer extends PetsApi {
@Override
Response201400<Pet, Error> createPet(PetCreate body);
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
@SecurityRequirement(name = "oauth2", scopes = {"write:pets"})
default ResponseEntity<?> createPetEndpoint(@RequestBody PetCreate body) {
return switch (createPet(body)) {
case Created r -> ResponseEntity.status(201).body(r.value());
case BadRequest r -> ResponseEntity.status(400).body(r.value());
default -> throw new IllegalStateException("Unexpected response type");
};
}
@DeleteMapping("/{petId}")
Void deletePet(@PathVariable("petId") PetId petId);
}
Java + Quarkus (Reactive)
Quarkus with Mutiny Uni<T> for reactive programming:
@Path("/pets")
public interface PetsApiServer extends PetsApi {
@Override
Uni<Response201400<Pet, Error>> createPet(PetCreate body);
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
default Uni<Response> createPetEndpoint(PetCreate body) {
return createPet(body).map(response -> switch (response) {
case Created r -> Response.status(201).entity(r.value()).build();
case BadRequest r -> Response.status(400).entity(r.value()).build();
default -> throw new IllegalStateException("Unexpected response type");
});
}
@DELETE
@Path("/{petId}")
Uni<Void> deletePet(@PathParam("petId") PetId petId);
}
Kotlin + JAX-RS
Idiomatic Kotlin with when expressions:
interface PetsApiServer : PetsApi {
override fun createPet(body: PetCreate): Response201400<Pet, Error>
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
fun createPetEndpoint(body: PetCreate): Response =
when (val response = createPet(body)) {
is Created<*> -> Response.status(201).entity(response.value).build()
is BadRequest<*> -> Response.status(400).entity(response.value).build()
else -> throw IllegalStateException("Unexpected response type")
}
@DELETE
@Path("/{petId}")
override fun deletePet(petId: PetId)
}
Scala + Http4s
Functional Scala with Cats Effect and auto-generated routes:
trait PetsApiServer extends PetsApi {
override def createPet(body: PetCreate): IO[Response201400[Pet, Error]]
def createPetEndpoint(body: PetCreate): IO[Response[IO]] =
createPet(body).flatMap {
case r: Created[Pet] => r.toResponse
case r: BadRequest[Error] => r.toResponse
}
override def deletePet(petId: PetId): IO[Unit]
/** HTTP routes - wire to your Http4s server */
def routes: HttpRoutes[IO] = HttpRoutes.of[IO] {
case req @ POST -> Root / "pets" =>
req.as[PetCreate].flatMap(createPetEndpoint)
case DELETE -> Root / "pets" / PetId(petId) =>
deletePet(petId).flatMap(_ => NoContent())
}
}
Shared API Contract
All server frameworks extend the same base API interface. This means you can:
- Test with mocks - Implement the base interface for unit tests
- Switch frameworks - Change frameworks without changing business logic
- Share types - Use the same request/response types everywhere