restnext-route

RestNext Route

License

License

GroupId

GroupId

org.restnext
ArtifactId

ArtifactId

restnext-route
Last Version

Last Version

0.3.5
Release Date

Release Date

Type

Type

jar
Description

Description

restnext-route
RestNext Route
Project Organization

Project Organization

RestNEXT
Source Code Management

Source Code Management

https://github.com/RestNEXT/restnext/tree/master/restnext-route

Download restnext-route

How to add to project

<!-- https://jarcasting.com/artifacts/org.restnext/restnext-route/ -->
<dependency>
    <groupId>org.restnext</groupId>
    <artifactId>restnext-route</artifactId>
    <version>0.3.5</version>
</dependency>
// https://jarcasting.com/artifacts/org.restnext/restnext-route/
implementation 'org.restnext:restnext-route:0.3.5'
// https://jarcasting.com/artifacts/org.restnext/restnext-route/
implementation ("org.restnext:restnext-route:0.3.5")
'org.restnext:restnext-route:jar:0.3.5'
<dependency org="org.restnext" name="restnext-route" rev="0.3.5">
  <artifact name="restnext-route" type="jar" />
</dependency>
@Grapes(
@Grab(group='org.restnext', module='restnext-route', version='0.3.5')
)
libraryDependencies += "org.restnext" % "restnext-route" % "0.3.5"
[org.restnext/restnext-route "0.3.5"]

Dependencies

compile (2)

Group / Artifact Type Version
org.restnext : restnext-core jar
pl.joegreen : lambda-from-string jar

test (1)

Group / Artifact Type Version
junit : junit jar

Project Modules

There are no modules declared in this project.

RestNEXT

N|Solid Powered By Netty

Build Status Maven Central Javadocs License

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.

Motivation

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.

Usage

  • 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;
    }
}

Installation

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>

TODOS

  • Write Tests
  • Add Javadoc and Code Comments

Fell free to contribute!

Special thanks

Thanks to my friend Wenderson Ferreira de Souza who contributed with some ideas and also encouraged me to start creating this software.

org.restnext

RestNEXT

Versions

Version
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.1
0.1.0