https://github.com/cchacin/microgen
An OpenAPI Spec Generator for Eclipse JakartaEE + Eclipse MicroProfile
https://github.com/cchacin/microgen
eclipse eclipse-microprofile jakartaee javaee javaee8 microprofile openapi3
Last synced: 5 months ago
JSON representation
An OpenAPI Spec Generator for Eclipse JakartaEE + Eclipse MicroProfile
- Host: GitHub
- URL: https://github.com/cchacin/microgen
- Owner: cchacin
- License: apache-2.0
- Created: 2018-08-15T07:56:22.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2023-03-15T13:58:17.000Z (over 2 years ago)
- Last Synced: 2024-04-16T19:17:10.591Z (over 1 year ago)
- Topics: eclipse, eclipse-microprofile, jakartaee, javaee, javaee8, microprofile, openapi3
- Language: Java
- Homepage: https://microgen.io/
- Size: 4.5 MB
- Stars: 5
- Watchers: 2
- Forks: 6
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
Awesome Lists containing this project
README

# MicroGen
MicroGen is a tool to generate java code based on an [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md) Spec file.
## Features
- Server API Contract (JAX-RS)
- Request and Response java objects
- Inner static `Builder` class and utility methods
- Enum value classes
- `@BeanParams` for request parameters
- Maven Archetype to quick start a JakartaEE + MicroProfile application
- Dockerfile(s) with a JakartaEE + MicroProfile application server## User Guide
Given an OpenAPI Spec file:
```yaml
openapi: 3.0.0
info:
description: This is a sample server Petstore server.
version: 1.0.0
title: Swagger Petstore
tags:
- name: pet
description: Everything about your Pets
paths:
/pet:
post:
tags:
- pet
summary: Add a new pet to the store
description: ''
operationId: addPet
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
$ref: '#/components/requestBodies/Pet'
components:
requestBodies:
Pet:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
required: true
schemas:
Pet:
type: object
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
category:
$ref: '#/components/schemas/Category'
name:
type: string
example: doggie
photoUrls:
type: array
items:
type: string
tags:
type: array
items:
$ref: '#/components/schemas/Tag'
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
```MicroGen will generate the following:
#### Server API Contract (JAX-RS)
JAX-RS interface with all the annotations necessary annotations
```java
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.MicroGen")
public interface PetApi {
/**
* Add a new pet to the store
*
* @param pet Pet object that needs to be added to the store (required)
* @return {@code java.util.concurrent.CompletionStage}
*/
@javax.ws.rs.POST
@javax.ws.rs.Path("pet")
@javax.ws.rs.Consumes({"application/json", "application/xml"})
java.util.concurrent.CompletionStage addPet(
@javax.validation.constraints.NotNull @javax.validation.Valid Pet pet
) throws javax.ws.rs.WebApplicationException;
.
.
.
}
```### `@BeanParams` for request parameters
`@BeanParams` wrapper class to minimize the breaking changes in the Java API contract, this includes:
- `@PathParam`'s
- `@QueryParam`'s
- `@FormParam`'s
- `@HeaderParam`'s
- `@CookieParam`'sBut also the additional:
- `@Context UriInfo`
- `@Context HttpHeaders````java
public class AddPetParams {
@javax.ws.rs.core.Context
public javax.ws.rs.core.HttpHeaders coreHttpHeaders;public AddPetParams coreHttpHeaders(
final javax.ws.rs.core.HttpHeaders coreHttpHeaders
) {
this.coreHttpHeaders = coreHttpHeaders;
return this;
}@javax.ws.rs.core.Context
public javax.ws.rs.core.UriInfo coreUriInfo;public AddPetParams coreUriInfo(
final javax.ws.rs.core.UriInfo coreUriInfo
) {
this.coreUriInfo = coreUriInfo;
return this;
}
}
```### Request and Response objects:
Generate the Request and Response java objects with the `Json-b` annotations:
- `@JsonbProperty`
- `@JsonbCreator`
- `@JsonbPropertyOrder`
- `toString()`
- `equals`
- `hashCode`
- Inner static `Builder` class and utility methodsCOMING SOON: Using immutables.org library
```java
/**
* Pet
*/
@javax.json.bind.annotation.JsonbPropertyOrder({
Pet.JSON_PROPERTY_ID,
Pet.JSON_PROPERTY_CATEGORY,
Pet.JSON_PROPERTY_NAME,
Pet.JSON_PROPERTY_PHOTO_URLS,
Pet.JSON_PROPERTY_TAGS,
Pet.JSON_PROPERTY_STATUS
})
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.MicroGen")
@io.quarkus.runtime.annotations.RegisterForReflection
public final class Pet {
private final java.util.OptionalLong id;
public static final String JSON_PROPERTY_ID = "id";@javax.validation.Valid
private final java.util.Optional category;
public static final String JSON_PROPERTY_CATEGORY = "category";@javax.validation.constraints.NotNull
private final String name;
public static final String JSON_PROPERTY_NAME = "name";@javax.validation.constraints.NotNull
private final java.util.List photoUrls;
public static final String JSON_PROPERTY_PHOTO_URLS = "photoUrls";@javax.validation.Valid
private final java.util.Optional> tags;
public static final String JSON_PROPERTY_TAGS = "tags";private final StatusEnum status;
public static final String JSON_PROPERTY_STATUS = "status";@javax.json.bind.annotation.JsonbCreator
public Pet(
@javax.json.bind.annotation.JsonbProperty("id")
final java.util.OptionalLong id,
@javax.json.bind.annotation.JsonbProperty("category")
final java.util.Optional category,
@javax.json.bind.annotation.JsonbProperty("name")
final String name,
@javax.json.bind.annotation.JsonbProperty("photoUrls")
final java.util.List photoUrls,
@javax.json.bind.annotation.JsonbProperty("tags")
final java.util.Optional> tags,
@javax.json.bind.annotation.JsonbProperty("status")
final StatusEnum status
) {
this.id = id;
this.category = category;
this.name = name;
this.photoUrls = photoUrls;
this.tags = tags;
this.status = status;
}// getter omitted
// more details explained below
}
```#### Inner static factory builder to make easier the instantiation:
```java
public static Builder builder() {
return Builder.create();
}public static final class Builder {
private java.util.OptionalLong id;
private java.util.Optional category;
private String name;
private java.util.List photoUrls;
private java.util.Optional> tags;
private StatusEnum status;private Builder() {
}public static Builder create() {
return new Builder();
}public Builder setId(final java.util.OptionalLong id) {
this.id = id;
return this;
}
// more info omitted
}
```### Enum values
Generating all the enum values with the `@JsonbSerializer`'s and `@JsonbDeserializer`'s
```java
@javax.json.bind.annotation.JsonbTypeSerializer(Pet.StatusEnumSerializer.class)
@javax.json.bind.annotation.JsonbTypeDeserializer(Pet.StatusEnumDeserializer.class)
public static enum StatusEnum {AVAILABLE("available"),
PENDING("pending"),
SOLD("sold");private final String value;
StatusEnum(final String value) {
this.value = value;
}public String getValue() {
return this.value;
}@Override
public String toString() {
return String.valueOf(this.value);
}@javax.json.bind.annotation.JsonbCreator
public static StatusEnum fromValue(final String text) {
return java.util.Arrays.stream(StatusEnum.values())
.filter(b -> java.util.Objects.equals(String.valueOf(b.value), text))
.findFirst()
.orElse(null);
}
}
```#### Enum's `Jsonb` Serializers/Deserializer
```java
public static class StatusEnumSerializer implements javax.json.bind.serializer.JsonbSerializer {public StatusEnumSerializer() { }
@Override
public void serialize(
StatusEnum aEnum,
javax.json.stream.JsonGenerator jsonGenerator,
javax.json.bind.serializer.SerializationContext serializationContext) {
jsonGenerator.write(aEnum.value);
}
}public static class StatusEnumDeserializer implements javax.json.bind.serializer.JsonbDeserializer {
public StatusEnumDeserializer() {}
@Override
public StatusEnum deserialize(
javax.json.stream.JsonParser jsonParser,
javax.json.bind.serializer.DeserializationContext deserializationContext,
java.lang.reflect.Type type) {
return StatusEnum.fromValue(jsonParser.getString());
}
}
```### Using MicroGen with the Maven Archetype
Execute this command
```bash
$ mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=example \
-DarchetypeGroupId=io.microgen \
-DarchetypeArtifactId=microgen-archetype
```Check what is created
```bash
$ cd example && tree . --dirsfirst
example
├── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── JAXRSConfiguration.java
│ ├── resources
│ │ └── META-INF
│ │ ├── microprofile-config.properties
│ │ └── openapi.yml
│ └── webapp
│ └── WEB-INF
│ └── beans.xml
├── Dockerfile
├── README.md
├── mvnw
├── mvnw.cmd
└── pom.xml9 directories, 9 files
```Implement the JAX-RS API contract
```java
@Path("v1")
@ApplicationScoped
public class PetResource implements PetApi {@Override
public CompletionStage addPet(Pet pet) throws WebApplicationException {
return CompletableFuture.completedFuture(
Response.noContent().build()
);
}@Override
public CompletionStage getPetById(GetPetByIdParams params) throws WebApplicationException {
return CompletableFuture.completedFuture(
Response.ok(
Pet.builder()
.setId(OptionalLong.of(1))
.setName("pet")
.build()
).build()
);
}
```Run and enjoy
```bash
$ ./mvnw clean install
``````bash
$ docker rm -f example || true && docker run -d -p 9080:9080 --name example com.example/example:1.0-SNAPSHOT
``````bash
$ curl -s -X GET -H "Accept: application/json" http://localhost:9080/api/v1/pet/1 | jq .
{
"category": {
"id": 1,
"name": ""
},
"id": 1,
"name": "name",
"status": "available"
}
```### Advance Features
### Dependencies
| Library | Version | License |
|:---------------------|:--------|:--------|
| Eclipse JakartaEE | 8.0.0 | |
| Eclipse MicroProfile | 3.0 | |
| OpenAPI Tools | 4.1.1 | |
| Immutables | 2.7.5 | |[](https://forthebadge.com) [](https://forthebadge.com)
[](https://forthebadge.com) [](https://forthebadge.com)




[](https://maven-badges.herokuapp.com/maven-central/io.microgen/MicroGen)
[](http://makeapullrequest.com) [](https://dependabot.com)