RestNext is a framework (extremely simple to use) built on top of Netty framework (4.1.x) with automatic security and route scanning approach for micro services. The RestNext biggest difference is the ability to register/unregister routes and security for routes without having to restart the application server. Where are cross cutting system functionalities.
After several searches on the WWW, I have not found a framework easy to use, highly performative and with the functionality to deploy routes without the need to restart the application server. So I decided to implement my framework.
-
Simple usage:
class SimpleExample { public static void main(String[] args) { ServerInitializer .route("/", req -> Response.ok("it works").build()) .route("/stream", req -> Response.ok("large content").chunked().build()) .start(); } }
-
More complete example:
class MoreCompleteExample { public static void main(String[] args) { Function<Request, Response> provider = request -> Response.ok("ok").build(); Function<Request, Response> provider2 = r -> Response.ok(r.getParams().getFirst("name")).build(); Function<Request, Response> eTagProvider = request -> { EntityTag entityTag = new EntityTag("contentCalculatedEtagValue"); return Optional.ofNullable(request.evaluatePreconditions(entityTag)) .orElse(Response.ok().tag(entityTag)) .build(); }; Function<Request, Boolean> secureProvider = request -> true; Function<Request, Boolean> hmacSecureProvider = request -> true; Route.Mapping[] routes = { Route.Mapping.uri("/", provider).build(), Route.Mapping.uri("/regex/\\d+", eTagProvider).build(), Route.Mapping.uri("/param/{name}", provider2).build() }; Security.Mapping[] secures = { Security.Mapping.uri("/", secureProvider).build(), Security.Mapping.uri("/regex/\\d+", r -> false).build(), Security.Mapping.uri("/param/{name}", hmacSecureProvider).build() }; ServerInitializer.builder() // automatic registration approach with default path. ($user.dir/route | $user.dir/security) .enableRoutesScan() .enableSecurityRoutesScan() // automatic registration approach with custom path. .enableRoutesScan(SystemPropertyUtils.getPath("user.home")) .enableSecurityRoutesScan(Paths.get(System.getProperty("user.home"), "secure")) // manual registration approach. .route("ping", req -> Response.ok("pong").build()) .route(uri, etagProvider) .secure(uri, req -> true) .secure(uri, secureProvider) // multiple manual registration approach. .routes(routes) .secures(secures) // start as https .ssl() // read timeout .timeout(Duration.ofSeconds(30)) // enable compression .enableCompression() //... and other options // build and start the server. .start(); } }
NOTE:
When you enable route/security scanning, the default or custom directory path provided will be monitored to listen to event of creation, modification and deletion of the .jar file. For automatic registration to work properly, the .jar file should contain the following directory structure:
/META-INF/route/*.xml
/META-INF/security/*.xml
Each folder (route/security) can contain as many XML files you want, and the name of the XML file can be any name you want.
routes.xml example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<routes xmlns="http://www.restnext.org/routes">
<route>
<path>/test</path>
<provider>br.com.thiaguten.route.Provider::anyMethodNameYouWant</provider>
<methods>
<method>GET</method>
<method>POST</method>
</methods>
<medias>
<media>text/plain</media>
<media>application/json</media>
</medias>
</route>
<route>
<path>/test/{name}</path>
<provider>br.com.thiaguten.route.Provider::test2</provider>
</route>
<route>
<path>/test/regex/\\d+</path>
<provider>br.com.thiaguten.route.Provider::test3</provider>
<enable>false</enable>
</route>
</routes>
The route XML property value must have Method Reference syntax and the class method must be public and static, respecting the following signature:
class Provider {
public static Response anyMethodNameYouWant(Request request) {
// process the request and write some response.
return Response.ok().build();
}
}
security.xml example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<securities xmlns="http://www.restnext.org/securities">
<security>
<path>/test</path>
<provider>br.com.thiaguten.security.Provider::anyMethodNameYouWant</provider>
</security>
<security>
<path>/test/{name}</path>
<provider>br.com.thiaguten.security.Provider::test2</provider>
<enable>false</enable>
</security>
<security>
<path>/test/regex/\\d+</path>
<provider>br.com.thiaguten.security.Provider::test3</provider>
</security>
</securities>
The security XML property value must have Method Reference syntax and the class method must be public and static, respecting the following signature:
class Provider {
public static boolean anyMethodNameYouWant(Request request) {
// validate the request.
return true;
}
}
RestNEXT requires JDK 8 to run.
Download and extract the latest pre-built release.
Maven Artifact:
<dependency>
<groupId>org.restnext</groupId>
<artifactId>restnext-server</artifactId>
<version>0.3.5</version>
</dependency>
- Write Tests
- Add Javadoc and Code Comments
Thanks to my friend Wenderson Ferreira de Souza who contributed with some ideas and also encouraged me to start creating this software.