All Projects → buremba → Netty Rest

buremba / Netty Rest

Licence: apache-2.0
Yet another high performance REST server based on Netty

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Netty Rest

Farwest
Framework for building RESTful HATEOAS-driven applications.
Stars: ✭ 18 (-83.18%)
Mutual labels:  rest-api, http-server
Mofuw
mofuw is *MO*re *F*aster, *U*ltra minimal *W*ebserver.
Stars: ✭ 107 (+0%)
Mutual labels:  high-performance, http-server
Sylar
C++高性能分布式服务器框架,webserver,websocket server,自定义tcp_server(包含日志模块,配置模块,线程模块,协程模块,协程调度模块,io协程调度模块,hook模块,socket模块,bytearray序列化,http模块,TcpServer模块,Websocket模块,Https模块等, Smtp邮件模块, MySQL, SQLite3, ORM,Redis,Zookeeper)
Stars: ✭ 895 (+736.45%)
Mutual labels:  high-performance, http-server
Zaver
Yet another fast and efficient HTTP server
Stars: ✭ 673 (+528.97%)
Mutual labels:  high-performance, http-server
T Io
解决其它网络框架没有解决的用户痛点,让天下没有难开发的网络程序
Stars: ✭ 1,331 (+1143.93%)
Mutual labels:  http-server, netty
Cowboy
Small, fast, modern HTTP server for Erlang/OTP.
Stars: ✭ 6,533 (+6005.61%)
Mutual labels:  high-performance, http-server
Server
Serve your Rubix ML models in production with scalable stand-alone model inference servers.
Stars: ✭ 30 (-71.96%)
Mutual labels:  rest-api, http-server
Gramework
Fast and Reliable Golang Web Framework
Stars: ✭ 354 (+230.84%)
Mutual labels:  rest-api, high-performance
Async Gamequery Lib
A high-performance java game query library designed for steam/source based games and others
Stars: ✭ 88 (-17.76%)
Mutual labels:  rest-api, netty
Nettygameserver
使用netty4.X实现的手机游戏分布式服务器,支持tcp,udp,http,websocket链接,采用protobuf自定义协议栈进行网络通信,支持rpc远程调用,使用mybatis3支持db存储分库分表,支持异步mysql存储,db保存时同步更新reids缓存。 使用ExcelToCode工程,将excel数据生成java类和json数据字典,DictService直接读取json,减少数据字典部分代码。使用game-executor工程,增加游戏内的异步事件全局服务, 支持事件sharding,均衡的异步执行事件逻辑
Stars: ✭ 1,203 (+1024.3%)
Mutual labels:  http-server, netty
Brpc Java
Java implementation for Baidu RPC, multi-protocol & high performance RPC.
Stars: ✭ 647 (+504.67%)
Mutual labels:  high-performance, netty
Jupiter
Jupiter是一款性能非常不错的, 轻量级的分布式服务框架
Stars: ✭ 1,372 (+1182.24%)
Mutual labels:  high-performance, netty
Xxl Rpc
A high performance, distributed RPC framework.(分布式服务框架XXL-RPC)
Stars: ✭ 493 (+360.75%)
Mutual labels:  high-performance, netty
Go Book Store Api
Go Sample project to understand Mysql CRUD operation with best practises Includes logging, JWT, Swagger and Transactions
Stars: ✭ 18 (-83.18%)
Mutual labels:  rest-api, http-server
Libhttpserver
C++ library for creating an embedded Rest HTTP server (and more)
Stars: ✭ 464 (+333.64%)
Mutual labels:  rest-api, http-server
Liberator
An Elixir library for building RESTful applications.
Stars: ✭ 28 (-73.83%)
Mutual labels:  rest-api, http-server
Restana
Super fast and minimalist framework for building REST micro-services.
Stars: ✭ 341 (+218.69%)
Mutual labels:  rest-api, http-server
Kotlin Ktor Exposed Starter
Starter RESTful service with websocket notifications using Kotlin, Ktor and Exposed with H2, HikariCP and FlyWay
Stars: ✭ 343 (+220.56%)
Mutual labels:  rest-api, netty
Generator Http Fake Backend
Yeoman generator for building a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 49 (-54.21%)
Mutual labels:  rest-api, http-server
Violetear
Go HTTP router
Stars: ✭ 100 (-6.54%)
Mutual labels:  rest-api, http-server

Netty RESTful Server

Netty-rest is a high performance HTTP and WebSocket server implementation based on Netty. It uses javax.ws.rs annotations and generates Java bytecode at runtime in order to provide best performance. It basically maps the java methods to endpoints and takes care of validation, serialization / deserialization, authentication and designed for minimum overhead and maximum performance. It can generate Swagger specification automatically so that you can generate client libraries, API documentation easily.

Here is a simple example:

import org.rakam.server.http.HttpServer;
import org.rakam.server.http.HttpServerBuilder;
import org.rakam.server.http.HttpService;
import org.rakam.server.http.annotations.*;

import javax.ws.rs.Path;
import java.util.Arrays;
import java.util.HashSet;

public class HttpServerTest {
    public static void main(String[] args) throws Exception {
        HttpServer build = new HttpServerBuilder()
                .setHttpServices(new HashSet<>(Arrays.asList(new CustomHttpServer()))).build();

        build.bindAwait("127.0.0.1", 7847);
    }

    @Path("/")
    public static class CustomHttpServer extends HttpService {
        @JsonRequest
        @ApiOperation(value = "Parameter demo endpoint")
        @Path("/parameter")
        public String testJsonParameter(@ApiParam("param1") String param1, @ApiParam("param2") int param2) {
            return param1 + param2;
        }
    }
}

And then run the following CURL command:

curl -X POST http://127.0.0.1:7847/parameter \
    -H 'content-type: application/json' \
    -d '{"param1": "Hello", "param2": 2}'

If you don't pass one of the parameters, the server will return 400 response, you can also use complex java beans in parameters and method return signature. The library uses Jackson for serialization of the object that you passed and deserialization of the JSON attributes. It will be mapped to the parameters and the method will be invoked for the API calls.

Here is the complete list of examples for basic operations:

import org.rakam.server.http.HttpServer;
import org.rakam.server.http.HttpServerBuilder;
import org.rakam.server.http.HttpService;
import org.rakam.server.http.annotations.*;

import javax.ws.rs.Path;
import java.util.Arrays;
import java.util.HashSet;

public class HttpServerTest {
    public static void main(String[] args) throws Exception {
        HttpServer build = new HttpServerBuilder()
                .setHttpServices(new HashSet<>(Arrays.asList(new SimpleHttpService()))).build();

        build.bindAwait("127.0.0.1", 7847);
    }

    @Path("/")
    public static class SimpleHttpService extends HttpService {
        @JsonRequest
        @ApiOperation(value = "Bean Demo endpoint")
        @Path("/bean")
        public String testJsonBean(@BodyParam DemoBean demo) {
            return demo.toString();
        }

        @JsonRequest
        @ApiOperation(value = "Parameter demo endpoint")
        @Path("/parameter")
        public String testJsonParameter(@ApiParam("param1") String param1, @ApiParam("param2") int param2) {
            return param1 + param2;
        }

        // You can also use CompletableFuture for async operations
        @JsonRequest
        @ApiOperation(value = "Parameter demo endpoint")
        @Path("/future-parameter")
        public CompletableFuture<String> futureTestJsonParameter(@ApiParam("param1") String param1, @ApiParam("param2") Integer param2, @ApiParam(value = "param3", required = false) Long param3) {
            CompletableFuture<String> future = new CompletableFuture<>();
            future.complete(param1 + param2 + param3);
            return future;
        }

        @JsonRequest
        @ApiOperation(value = "Parameter demo endpoint")
        @Path("/header-cookie-parameter")
        public CompletableFuture<String> futureTestJsonParameter(@HeaderParam("my-custom-header") String param1, @CookieParam("my-cookie-param") String param2) {
            CompletableFuture<String> future = new CompletableFuture<>();
            future.complete(param1 + param2);
            return future;
        }

        @JsonRequest
        @ApiOperation(value = "Raw demo endpoint")
        @Path("/raw")
        public void testJsonParameter(RakamHttpRequest request) {
            request.response("cool").end();
        }

        public static class DemoBean {
            public final String test;

            @JsonCreator
            public DemoBean(@JsonProperty("test") String test) {
                this.test = test;
            }
        }
    }
}

Authentication

You can implement API key based authentification easily with custom parameters. Here is a simple example:

public class HttpServerTest {
    public static void main(String[] args) throws Exception {
        HttpServer build = new HttpServerBuilder()
                .setCustomRequestParameters(ImmutableMap.of("projectId", method -> (node, request) -> {
                    String apiKey = request.headers().get("api_key");
                    try {
                        return apiKeyService.findProject(apiKey);
                    } catch (NotFoundException e) {
                        throw new HttpRequestException("API key is invalid", HttpResponseStatus.FORBIDDEN);
                    }
                })).build();
                .setHttpServices(new HashSet<>(Arrays.asList(new CustomHttpServer()))).build();

        build.bindAwait("127.0.0.1", 7847);
    }

    @Path("/")
    public static class CustomHttpServer extends HttpService {
        @JsonRequest
        @ApiOperation(value = "Parameter demo endpoint")
        @Path("/list")
        public List<String> testJsonParameter(@Named("projectId") int id) {
            return db.getItemsForProject(id);
        }
    }
}

Request hooks

You can add hooks to API calls before the methods are executed and also after they're executed. Here is an example:

HttpServer build = new HttpServerBuilder()
    .setHttpServices(new HashSet<>(Arrays.asList(new SimpleHttpService())))
    .addJsonPreprocessor(new RequestPreprocessor() {
        @Override
        public void handle(RakamHttpRequest request) {
            System.out.println(request.getUri());
        }
    }, (method) -> true)
    .addPostProcessor(new ResponsePostProcessor() {
        @Override
        public void handle(FullHttpResponse response) {
            System.out.println(response.getStatus());
        }
    }, (method) -> true).build();

Websockets

Although the library is designed for RESTFul APIs, it also has support for websockets:

public class HttpServerTest {
    public static void main(String[] args) throws Exception {
        HttpServer build = new HttpServerBuilder()
                .setWebsocketServices(new HashSet<>(Arrays.asList(new SimpleWebhookService()))).build();

        build.bindAwait("127.0.0.1", 7847);
    }
    
    public class SimpleWebhookService extends WebSocketService {
        private String id;

        @Override
        public void onOpen(WebSocketRequest request) {
            id = UUID.randomUUID().toString();
            System.out.println(String.format("%s: started", id));
        }

        @Override
        public void onMessage(ChannelHandlerContext ctx, String message) {
            System.out.println(String.format("%s: sent %s", id, message));
        }

        @Override
        public void onClose(ChannelHandlerContext ctx) {
            System.out.println(String.format("%s: closed", id));
        }
    }
}

Exception handling

Exception hooks are particularly useful for logging them to your API Exception tracker. If you throw HttpRequestException in your code, you can set the API call status code and error message but if the Exception is not an instance of HttpRequestException, the server will return 500 status code.

HttpServer build = new HttpServerBuilder()
      .setHttpServices(new HashSet<>(Arrays.asList(new SimpleHttpService())))
      .setExceptionHandler(new HttpServerBuilder.ExceptionHandler() {
          @Override
          public void handle(RakamHttpRequest request, Throwable e) {

          }
      }).build();

Swagger

The library automatically generates the Swagger spec for you. You can see the specification in /api/swagger.json path. Here is a real example. I also maintaion a Slate documentation generator from Swagger specification. This library is compatible with the API documentation generator, here is an example.

You can set your Swagger instance using HttpServerBuilder.setSwagger. Here is an example:

Info info = new Info()
        .title("My API Documentation")
        .version("0.1")
        .description("My great API")
        .contact(new Contact().email("[email protected]"))
        .license(new License()
                .name("Apache License 2.0")
                .url("http://www.apache.org/licenses/LICENSE-2.0.html"));

Swagger swagger = new Swagger().info(info)
        .host("app.myapp.io")
        .basePath("/")
        .tags(ImmutableList.copyOf(tags))
        .securityDefinition("api_key", new ApiKeyAuthDefinition().in(In.HEADER).name("api_key"));

new HttpServerBuilder().setSwagger(swagger).build()

Misc

If you run the library on Linux, it will try to use Epoll but you can disable it with HttpServerBuilder.setUseEpollIfPossible

You can also use your own Jackson mapper with HttpServerBuilder.setMapper if you have custom JSON serializers / deserializers.

We also support Proxy Protocol if you run the HTTP server behind the load balancer. You can enable it with HttpServerBuilder.setProxyProtocol.

You can take a look at examples in Rakam which heavily uses netty-rest: https://github.com/rakam-io/rakam/blob/master/rakam/src/main/java/org/rakam/plugin/user/UserHttpService.java

Profiling

The library exposes an MBean called org.rakam.server.http:name=SHttpServer. If you attach the JVM instance you can call getActiveClientCount and getActiveRequests for the list of active request the execution time of each request.

To be done

  • Javadocs
  • API usage monitoring tool
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].