Blog

Source javadoc tag

I've added a Javadoc taglet for quickly linking to source code on GitHub:  "{@source}" or "{@source label}"

It can be added to class-level javadocs like so:

Based on the file location in the source tree, it will calculate the GitHub link:

I think this will be particularly useful if you want to provide source links in example code javadocs.

Spring Boot Integration

Hi all,

I've made some modifications to the work that Marcelo contributed for the Spring Boot integration.  I still consider this in flux though and suggestions are welcome.

Here's the updated project layout:

Here's what it looks like to start up a Spring app with Juneau Examples REST resources:

Another option is to add the @JuneauRest annotation on your configuration bean method:

The root resource will be initialized with the SpringRestResourceResolver which allows for child resources to be defined as injectable Spring beans.

The app can be launched from Eclipse using the juneau-examples-rest-springboot.launch file.  It will bring up the REST examples on port 5000.


In 8.0, I'll be adding the concept of a default system configuration.  One of the annoyances of setting up the Juneau REST resources to work with Spring Boot is that you have to manually set the "juneau.configFile" system property so that our servlets know where to look for configuration.  With a default system configuration, this requirement goes away.

Being added is a Config.getSystemDefault() static method that returns the system default configuration.

If "juneau.configFile" is set, it will continue to look for a configuration file with that name in either the home directory or classpath.  If not, then it will look for the following:

  • In the home directory:
    • <jar-name>.cfg
    • Any files that end with .cfg in the JVM home directory.
  • In the classpath (as part of the jar):
    • <jar-name>.cfg
    • juneau.cfg
    • default.cfg

Note that by placing it in your jar, you gain having everything packaged as a single uber-jar, but lose persistence (since it's not writeable).

Also being added:

  • ConfigClasspathStore - A ConfigStore for reading configs from the context classpath.  Note that this is a read-only store.
  • ConfigStore.exists(name) - New method on interface for checking for the existence of a configuration.

Your REST servlets can refer to the system default configuration with the special keyword "SYSTEM_DEFAULT".

For example:

// Always use system default
@RestResource(config="SYSTEM_DEFAULT")
// Use system property if set or the system default if not.
@RestResource(config="$S{juneau.configFile,SYSTEM_DEFAULT}")


There is a corresponding Config.setSystemDefault(Config) for overriding the system default configuration.   

The Pet Store application has been upgraded to use JPA for persistence.  It's now possible to marshall JPA beans using Juneau serializers and parsers.

For example, the Pet bean below combines JPA and Juneau annotations:

One noted enhancements is that you can now define bean-property annotations (e.g. @BeanProperty, @Html, @Schema, ...) on private bean fields just like JPA annotations.

Also, the @Schema annotation has been enhanced to provide more information for bean properties in the auto-generated Swagger:

New in Juneau 7.2.1: 

Method and argument annotations such as @RestMethod, @Path, etc..., are now inheritable from parent classes and interfaces.  

This means you can now define the same Java interface for both your server and client side APIs.  

For example, the Pet Store application now defines a top-level PetStore interface:

The PetStoreResource class implements this interface using the normal RestServlet API.

In this particular case, the @RestMethod annotations are specified in the implementation class, although they could be located in the interface as well.

The PetStore interface can be used as the remote proxy interface like so:

The advantages to this design approach are:

  • It's much easier to keep server and client side APIs in sync since they're working off the same interface.
  • The annotations can be moved into your interface where they won't interfere with the readability of your servlet code.


There's a behavior change being made to the default value on @RestMethod(path).  If not specified, the value is now inferred from the Java method name.

This can result in cleaner-looking code.

The previous behavior was to default to the value "/*".

More information can be found here:

http://juneau.apache.org/site/apidocs_preview/overview-summary.html#juneau-rest-server.RestMethod

Documentation reorg

FYI....I've broken up the overview.html file into individual topics:  

The overview document was just getting too unwieldy (the Eclipse HTML editor struggled with it).  The smaller parts should be easier to work with, and reorganizing pages should now be much easier.  Also, broken links should now be fewer in number.

The DocGenerator class will take all the individual pages and combine them into the same overview.html page as before.

The generator is not currently part of the build process so it has to be executed manually to generate the overview.   

In 7.2, we're introducing auto-validation of Swagger annotations.  What this means is that the various Swagger annotations are not just used for populating the Swagger JSON / UI, but are actively used in serializing/parsing/validating the HTTP parts.

For example:

This example shows a parameter of type PetStatus[] (which happens to be enums, but could also be POJOs as well).  The type and collectionFormat attributes tell the framework to parse the incoming value as a comma-delimited list.  The _enum shows the possible valid values.  A BadRequest is thrown if any values don't match.  

Part of this change includes combining the client-side and server-side annotations into a single set of annotations (no more confusing org.apache.juneau.remoteable.Query with org.apache.juneau.rest.annotation.Query).

Features include:

  • Support for all of Swagger 2.0.
  • Auto-validation for:
    • Numeric values (minimummaximumexclusiveMinimumexclusiveMaximummultipleOf).
    • String values (minLengthmaxLengthenum).
    • Collection values (itemsminItemsmaxItemsuniqueItems).
    • Object values (propertiesmaxPropertiesminPropertiesadditionalProperties).
    • Existence of values (requiredallowEmptyValue).
  • Support for both client-side and server-side annotations.
  • Works on the Body annotation as well.  If the media-type of the body does not match an existing serializer/parser, then the Swagger rules are used for marshalling.
  • UON notation is still supported, so you can still represent arbitrary POJOs as any of the HTTP parts.  However, you have to explicitly specify format="uon".

Juneau 7.2.0 is close to release but there is still a considerable amount of documentation to be written.  The Javadocs on the classes themselves should be mostly complete, but much remains to be written in the overview document.

I've uploaded a preview of the Javadocs so far here:
http://juneau.apache.org/site/apidocs_preview/index.html

To help identify new and in-progress documentation, I've added temporary color coding to new and modified sections...

If there is any documentation lacking, now would be a good time to point it out (smile)

In 7.2.0, I'm adding support for POJO REST requests that don't include Accept and Media-Type headers.

Previously, if your requests did not contain Accept or Content-Type headers, you had to use Readers and Writers to work with the HTTP request and response bodies.  Otherwise you would get Not Acceptable (406) and Unsupported Media Type (415) response codes.  

This behavior is now being relaxed.  If your request does not contain media-type headers, then you can still used POJOs for requests and responses.

For example, this is a snippet from the Javadoc on the Body annotation describing the types of objects you can use in REST Java methods to represent the body of the request:

JUnit Test Results

FYI....JUnit testcase results have been added to the Jenkins builds...

I'm adding the following classes to the juneau-rest-server module to allow you to unit test your REST resources without the need of running them in a servlet container:

Here's an example of it in use...

Instead of routing requests through a servlet container, it simply creates the RestContext object for the resource and calls the RestContext.getCallHandler().service(request, response); method with mocked-up ServletRequest and ServletResponse objects.

Here's what it looks like in expanded form:

In theory, everything should work identically to how it would behave in a servlet container, only faster and more efficient.

The MockRest object can also be used with the RestClient class to perform serverless client-side testing against REST resource classes:

This last feature is useful if you want to perform serverless unit testing of REST proxy interfaces.

 

 

Configurable look-and-feel

This change is being introduced in 7.1.1 to resolve the following feature request:

https://issues.apache.org/jira/projects/JUNEAU/issues/JUNEAU-82

 

The change introduces an external folder in the JVM working directory containing images and stylesheets used by the microservice:

The REST configuration section can be used to tailor the header and footer on the pages:

The BasicRestConfig interface (which defines the default settings for BasicRestServlet) is now defined as:

Note that the theme files are externally accessible and can be modified to produce any look-and-feel you desire.

The microservice still works without the files directory.  An embedded devops.css is included in the jar as a default spreadsheet.

If you're testing out changes in the theme stylesheets, you may want to set the following system property that prevents caching of those files so that you don't need to restart the microservice each time a change is made:

 

Quick update on the Swagger UI enhancements.

The design allows you to pull in Swagger from any of the following sources (or any combination):

  • Localized Swagger JSON files on the classpath.
  • Swagger defined on class-level and method-level annotations.
  • Swagger fragments defined in resource bundles.
  • Auto-detection if not found above (paths, methods, schemas, etc...).

The general idea is you can let Juneau auto-generate the Swagger documentation, or provide your own Swagger JSON, or do a combination of auto and manual.

 

Here's the Petstore app OPTIONS page based on the Swagger.io Petstore example...

 

Operations are expandable and gives you information about the schema.  

In this case, the schema information was auto-detected and generated using the JsonSchemaSerializer. 

 

Examples for all the supported types are provided via a select when an @Example-annotated method exists on the POJO class (or otherwise defined in the Swagger JSON).

 

For example, RDF....