{title:'juneau-petstore-api', created:'9.0.0'}

The juneau-petstore-api module contains the Java interface of our application and the DTOs that go along with it. These classes are meant to be shared between the server and client side code.

The PetStore class is our primary class for defining our application. It's a standard Java interface with annotations used to describe how the methods map to REST calls.

PetStore.java

| @Remote(path="/petstore") | public interface PetStore { | | //------------------------------------------------------------------------------------------------------------------ | // Pets | //------------------------------------------------------------------------------------------------------------------ | | /** | * Returns all pets in the database. | * | * @return All pets in the database. | * @throws NotAcceptable Unsupported Accept header specified. | */ | @RemoteGet("/pet") | public Collection getPets() throws NotAcceptable; | | /** | * Returns a pet from the database. | * | * @param petId The ID of the pet to retrieve. | * @return The pet. | * @throws IdNotFound Pet was not found. | * @throws NotAcceptable Unsupported Accept header specified. | */ | @RemoteGet("/pet/{petId}") | public Pet getPet( | @Path( | name="petId", | schema=@Schema(description="ID of pet to return") | ) | long petId | ) throws IdNotFound, NotAcceptable; | | /** | * Adds a pet to the database. | * | * @param pet The pet data to add to the database. | * @return Ok if successful. | * @throws IdConflict ID already in use. | * @throws NotAcceptable Unsupported Accept header specified. | * @throws UnsupportedMediaType Unsupported Content-Type header specified. | */ | @RemotePost("/pet") | public long createPet( | @Content( | schema=@Schema(description="Pet object to add to the store") | ) | CreatePet pet | ) throws IdConflict, NotAcceptable, UnsupportedMediaType; | | /** | * Updates a pet in the database. | * | * @param pet The pet data to add to the database. | * @return Ok if successful. | * @throws IdNotFound ID not found. | * @throws NotAcceptable Unsupported Accept header specified. | * @throws UnsupportedMediaType Unsupported Content-Type header specified. | */ | @RemotePut("/pet/{petId}") | public Ok updatePet( | @Content( | schema=@Schema(description="Pet object that needs to be added to the store") | ) | UpdatePet pet | ) throws IdNotFound, NotAcceptable, UnsupportedMediaType; | | /** | * Find all pets with the matching statuses. | * | * @param status The statuses to match against. | * @return The pets that match the specified statuses. | * @throws NotAcceptable Unsupported Accept header specified. | */ | @RemoteGet("/pet/findByStatus") | public Collection<Pet> findPetsByStatus( | @Query( | name="status", | schema=@Schema( | description="Status values that need to be considered for filter.", | required=true, | type="array", | collectionFormat="csv", | items=@Items( | type="string", | _enum="AVAILABLE,PENDING,SOLD", | _default="AVAILABLE" | ) | ) | ) | PetStatus[] status | ) throws NotAcceptable; | | /** | * Deletes the specified pet. | * | * @param apiKey Security key. | * @param petId ID of pet to delete. | * @return Ok if successful. | * @throws IdNotFound Pet not found. | * @throws NotAcceptable Unsupported Accept header specified. | */ | @RemoteDelete("/pet/{petId}") | public Ok deletePet( | @Header( | name="api_key", | schema=@Schema( | description="Security API key", | required=true | ) | ) | String apiKey, | @Path( | name="petId", | schema=@Schema(description="Pet id to delete") | ) | long petId | ) throws IdNotFound, NotAcceptable; | | /** | * Deletes all pets in the database. | * | * @return Ok if successful. | */ | @RemoteDelete("/pet") | public Ok deleteAllPets(); | | //------------------------------------------------------------------------------------------------------------------ | // Orders | //------------------------------------------------------------------------------------------------------------------ | | ... | }

@Remote and @RemoteX are client-side annotations used to map the method calls to REST and will be describe in the client code section.

@Path and @Body are used by both the client and server side code to map to REST artifacts on both sides.

Both sets of annotations are provided by pulling in the Juneau dependency below:

Maven Dependency

| <dependency> | <groupId>org.apache.juneau</groupId> | <artifactId>juneau-marshall</artifactId> | <version>9.x.x</version> | </dependency>

The Pet class is a DTO that gets serialized over the REST connection. It is also annotated with JPA annotations so that they can easily be stored in a JPA datastore on the server side.

Pet.java

| @Bean(typeName="Pet", properties="id,species,name,tags,price,status") | @Entity(name="PetstorePet") | public class Pet { | | @Column @Id @GeneratedValue | @Schema(description="Unique identifier for this pet.") | @Html(link="servlet:/pet/{id}") | private long id; | | @Column(length=50) | @Schema(description="Pet name.", minLength=3, maxLength=50) | private String name; | | @Column | @Schema(description="Price of pet.", maximum="999.99") | @Html(render=PriceRender.class) | private float price; | | ... | }

The annotations here are a combination of Juneau annotations for controlling marshalling (@Bean, @Html) and documentation/validation (@Schema), and JPA annoations for database persistence (@Entity, @Column).

Most applications may choose to have separate classes for DTOs and JPA beans since you typically are not going to want to expose server-side details to client-side code. In these examples however they were combined into the same classes for brevity.