Package org.refcodes.rest

What is this package for?

With this artifact you easily create you RESTful servers and REST clients. The refcodes-rest artifact lets you do it the Bare-Metal way, or the syntactic sugar (see client sugar or server sugar) way (meaning the use of statically imported methods):

RESTful server

  1. Instantiate the RESTful server
  2. Register your lambda expressions
  3. Start the RESTful server
Within three simple steps you implement your lightweight Java based RESTful server. Below, you see the three steps with the help of a little syntactic sugar:
 
 // STEP 1: We use a singleton with syntactic sugar instead of instantiating a HttpRestServer:
 import static org.refcodes.rest.HttpRestServerSugar.*;
 	... 
 	public static void main( String[] args ) {
 		// STEP 2: Using syntactic sugar, we register our lambda expression:
 		onGet( "/say/${name}=*", ( aResponse ) -> {
 			String name = aResponse.getWildcardReplacement( "name" );
 			aResponse.getHeaderFields().withContentType( MediaType.APPLICATION_JSON ).withAddCookie( "greeting", "Hello " + name + "!" );	
 			return "Hello " + name + "!" ;
 		} ).open();
 		// STEP 3: We open the HttpRestServer singleton on port 8080 using our syntactic sugar:
 		open( 8080 );
 	}
 	...
 
 
The TinyRestfulServer demo application uses syntactic sugar for setting up a RESTful server including command line arguments parsing.

REST client

  1. Instantiate the REST client
  2. Register your lambda expressions
  3. Fire the client's REST request
Again, within three simple steps you implement your lightweight Java based REST client. Below you see the three steps with the help of a little syntactic sugar:
 
 // STEP 1: We use a singleton with syntactic sugar instead of instantiating a HttpRestClient: 
 import static org.refcodes.rest.HttpRestClientSugar.*;
 	... 
 	public static void main( String[] args ) {
 		// STEP 2: Using syntactic sugar, we define our caller, including the response listener:
 		doGet( "http://mydomain:8080/say", ( aResponse ) -> {
 			... = aResponse.getResponse( SomeType.class );
 		} ).withRequest( ... ).open();
 		// STEP 3: We opened the caller so it fires the request to port 8080 of domain "mydomain"
 	}
 	...
 
 

How do I get set up?

To get up and running, include the following dependency (without the three dots "...") in your pom.xml:
 
 <dependencies>
 	...
 	<dependency>
 		<artifactId>refcodes-rest</artifactId>
 		<groupId>org.refcodes</groupId>
 		<version>x.y.z</version>
 	</dependency>
 	...
 </dependencies>
 
 
(please refer to Maven Central at "http://search.maven.org/#search|ga|1|g%3A%22org.refcodes%22" for the most current version)

If you want the framework to interoperate with SLF4J (http://www.slf4j.org/) logging, you may instead add the following dependencies to your pom.xml:

 
 <dependencies>
 	...
 	<dependency>
 		<artifactId>refcodes-rest</artifactId>
 		<groupId>org.refcodes</groupId>
 		<version>x.y.z</version>
 	</dependency>
 	<dependency>
 		<groupId>org.refcodes</groupId>
 		<artifactId>refcodes-logger-alt-slf4j</artifactId>
 		<version>x.y.z</version>
 	</dependency>
 	...
 </dependencies>
 
 
(please refer to Maven Central at "http://search.maven.org/#search|ga|1|g%3A%22org.refcodes%22" for the most current version)

The artifact is hosted directly at Maven Central (http://search.maven.org). Jump straight to the source codes at Bitbucket (https://bitbucket.org/refcodes/refcodes-rest). Read the artifact's javadoc at javadoc.io (http://www.javadoc.io/doc/org.refcodes/refcodes-rest).

How do I get started with the RESTful server?

Above you saw an example on how to setup your own RESTful service using syntactic sugar. One drawback of using syntactic sugar is that we can only make use of the one HttpRestServerSingleton (as of this syntactic sugar being the statically imported methods), preventing us from running multiple HttpRestServer instances on different ports in one Java application.

Lets do it the Bare-Metal way, which is not very complicated either, and which lets us instantiate as many HttpRestServer instances as we want:

 
 ...
 public static void main( String[] args ) {
 	// STEP 1: We instantiate our HttpRestServer:
 	HttpRestServer theRestServer = new HttpRestServerImpl();
 	// STEP 2: We register our lambda expression:
 	theRestServer.onGet( "/say/${name}=*", ( aResponse ) -> {
 		String name = aResponse.getWildcardReplacement( "name" );
 		aResponse.getHeaderFields().withContentType( MediaType.APPLICATION_JSON ).withAddCookie( "greeting", "Hello " + name + "!" );
 		return "Hello " + name + "!" ;
 	} ).open();
 	// STEP 3: We open the HttpRestServer instance on port 8080:
 	theRestServer.open( 8080 );
 }
 ...
 
 

The Locator-Pattern

Did you notice the Locator-Pattern "/say/${name}=*" above when registering your lambda? Subscribing your lambda expressions for incoming REST requests on specific locators, you may use a common wildcard syntax to define the lambda's locator pattern:
  • A single asterisk ("*") matches zero or more characters within a locator name.
  • A double asterisk ("**") matches zero or more characters across directory levels.
  • A question mark ("?") matches exactly one character within a locator name.
The single asterisk (*), the double asterisk (**) and the question mark (?) we refer to as wildcard: You get an array with all the substitutes of the wildcards using the method RestRequestEvent#getWildcardReplacements().

You may name a wildcard by prefixing it with "${someWildcardName}=". For example a named wildcard may look as follows: "${arg1}=*" or "${arg2}=**" or "${arg3}=?" or as of the example above "/say/${name}=*". When your "lambda" is being invoked, you can retrieve the wildcard substitution by the name of the wildcard which has been substituted (by parts of the incoming locator). You can get the text substituting a named wildcard using the method RestRequestEvent#getWildcardReplacement(String).

The RESTful server's bits and pieces

How do I get started with the REST client?

Above you saw an example on how to setup your own REST client using syntactic sugar. One drawback of using syntactic sugar is that we can only make use of the one HttpRestClientSingleton (as of this syntactic sugar being the statically imported methods), preventing us from running multiple HttpRestClient instances in one Java application (which is actually no real drawback, as the HttpRestClientSingleton can fire at any HTTP or HTTPS targets you wish to connect to).

Lets do it the Bare-Metal way, which is not very complicated either, and which lets us instantiate as many HttpRestClient instances as we want:

 
 ...
 public static void main( String[] args ) {
 	// STEP 1: We instantiate our HttpRestClient:
 	HttpRestClient theRestClient = new HttpRestClientImpl();
 	// STEP 2: We register our lambda expression:
 	theRestClient.doRequest( HttpMethod.POST, "http://mydomain:8080/say", ( aResponse ) -> {
 		String theResponse = aResponse.getResponse( String.class );
 	} ).withRequest( ... ).open();
 	// STEP 3: We opened the caller so it fires the request to port 8080 of domain "mydomain"
 }
 ...
 
 

The REST client's bits and pieces

Examples

Please refer to the example code at "https://bitbucket.org/refcodes/refcodes-rest/src/master/src/test/java/org/refcodes/rest". Also see "https://bitbucket.org/refcodes/refcodes-rest/src/master/src/test/java/org/refcodes/rest"