Skip to content

Jersey 2.x and Spring 4.x Integration with @Rest and RestResource

johnmcclean-aol edited this page Feb 26, 2015 · 2 revisions

By default we use Prototype Spring beans as Jersey Rest Resources - this is configurable per bean via the @Rest annotation or RestResource tag interface.

When using Singleton beans, state shouldn't be maintained across requests.

#Configuring Rest Endpoints

Microserver uses tag Annotations or tag Interfaces to identify Spring Beans as Jersey Rest endpoints. By default Microserver will pick up any class annotated with @Rest or implementing RestResource as a Rest end point.

e.g. Tagging with the @Rest annotation. (NB @Rest also tags the Class as a Spring component).

 @Rest
 @Path("/status")
 public class SimpleStatusResource {



 @GET
 @Produces("text/plain")
 @Path("/ping")
 public String ping() {
	
	return "ok";
 }


}

Or tagging with RestResource interface.

@Component
@Path("/status")
public class SimpleStatusResource implements RestResource {



@GET
@Produces("text/plain")
@Path("/ping")
public String ping() {
	
	return "ok";
}

}

Configuring your own tag Annotations and Interfaces

Particularly when running embedded Microservices within a single Spring context, you will want to separate Rest endpoints of each Microservice. You can specify tag resources on a per module (embedded Microservice) basis via overriding one (or both) of the following methods on the Module interface.

default List<Class> getRestResourceClasses() {
	return Arrays.asList(RestResource.class);
}
default List<Class> getRestAnnotationClasses() {
	return Arrays.asList(Rest.class);
}

getRestAnnotationClasses : defines the classes to be used as annotation tags getRestResourceClasses : defines the interface, abstract class, or even concrete classes to be used a Rest Resource tags.

Configuring embedded Microservices

Microservices should have no compile time dependencies on one and other. Embedding Microservices within the same Spring context is essential a performance (no network overhead), robustness (confidence a dependent service is live) and resource sharing (particularly for limited resources) optimisation, and should only happen at runtime. Building multiple "Microservices" with compile time dependencies, is building a somewhat modularised monolith.

You have a number of options for configuring the container.

  1. Have a separate Microservice for the container this should really be 1 line of non-boilerplate code, to define the Rest tags and start the Service.
  2. Use String names for Rest resources in the master / aggregator Microservice for the embedded group
  3. Combination of the above with generic aggregator Microservice that reads class strings from a property file.

Examples

Container with compile-time access to two Microservice projects

          new MicroServerStartup(new EmbeddedModule(asList(TestAppRestResource.class),"test-app"),
			new EmbeddedModule(asList(AltAppRestResource.class),"alternative-app"));

Master / Aggregator Microservice importing dependencies using Strings

   import static com.aol.micro.server.module.RestResourceTagBuilder.*;
   
   String aggregatorRest = "com.aol.micro.server.module.AggregatorRest";
   String secondaryRest = "com.aol.micro.server.module.SecondaryRest";
         new MicroServerStartup( new EmbeddedModule(restResourceTags(aggregatorRest),"aggregator"),
			new EmbeddedModule(restResourceTags(secondaryRest),"aggregator"));