All Projects → aesteve → Nubes

aesteve / Nubes

Licence: apache-2.0
Annotation layer on top of Vert.x 3

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Nubes

helloworld-web
Hello World web application in 39 different ways in Java
Stars: ✭ 18 (-85%)
Mutual labels:  vertx, spring-mvc
Pac4j
Security engine for Java (authentication, authorization, multi frameworks): OAuth, CAS, SAML, OpenID Connect, LDAP, JWT...
Stars: ✭ 2,097 (+1647.5%)
Mutual labels:  spring-mvc, vertx
alfresco-mvc
Glue between SpringMVC @controllers and Alfresco
Stars: ✭ 22 (-81.67%)
Mutual labels:  annotations, spring-mvc
Library-Spring
The library web application where you can borrow books. It's Spring MVC and Hibernate project.
Stars: ✭ 73 (-39.17%)
Mutual labels:  annotations, spring-mvc
S Mall Ssm
小小商城系统,JavaWEB项目,基于SSM,仿天猫页面,功能齐全,实现了自动处理关联查询的通用Mapper、抽象 BaseService 类、注解鉴权、参数注解校验等
Stars: ✭ 456 (+280%)
Mutual labels:  spring-mvc, annotations
Nb Springboot
NetBeans IDE plugin supporting programming with Spring Boot
Stars: ✭ 111 (-7.5%)
Mutual labels:  spring-mvc
Stock Price Viewer Microservices Part1
Spring Cloud services with 5 microservices - End to End Example
Stars: ✭ 115 (-4.17%)
Mutual labels:  spring-mvc
Kripton
A Java/Kotlin library for Android platform, to manage bean's persistence in SQLite, SharedPreferences, JSON, XML, Properties, Yaml, CBOR.
Stars: ✭ 110 (-8.33%)
Mutual labels:  annotations
Jeesite4
Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring MVC、Apache Shiro、MyBatis、Beetl、Bootstrap、AdminLTE),在线代码生成功能,包括核心模块如:组织机构、角色用户、菜单及按钮授权、数据权限、系统参数、内容管理、工作流等。采用松耦合设计;界面无刷新,一键换肤;众多账号安全设置,密码策略;在线定时任务配置;支持集群,支持SAAS;支持多数据源
Stars: ✭ 1,563 (+1202.5%)
Mutual labels:  spring-mvc
Knotx
Knot.x is a highly-efficient and scalable integration framework designed to build backend APIs
Stars: ✭ 119 (-0.83%)
Mutual labels:  vertx
Sensorannotations
Android - Annotate methods to use as listeners for a sensor.
Stars: ✭ 118 (-1.67%)
Mutual labels:  annotations
Jupytergraffiti
Create interactive screencasts inside Jupyter Notebook that anybody can play back
Stars: ✭ 114 (-5%)
Mutual labels:  annotations
Vertxui
Pure 100% java reactive-style client-side webpages with POJO traffic, jUnit GUI testing, declarative view-on-model, automatic browser reloading and more.
Stars: ✭ 112 (-6.67%)
Mutual labels:  vertx
Light Security
Light Security是一个基于jwt的权限控制框架,支持与Spring Boot配合使用,支持Spring MVC与WebFlux
Stars: ✭ 116 (-3.33%)
Mutual labels:  spring-mvc
Typical
Typical: Fast, simple, & correct data-validation using Python 3 typing.
Stars: ✭ 111 (-7.5%)
Mutual labels:  annotations
Advanced Vertx Guide
A gentle guide for advanced Vert.x users
Stars: ✭ 118 (-1.67%)
Mutual labels:  vertx
Spring Webmvc Pac4j
Security library for Spring Web MVC: OAuth, CAS, SAML, OpenID Connect, LDAP, JWT...
Stars: ✭ 110 (-8.33%)
Mutual labels:  spring-mvc
Router
🍭灵活的组件化路由框架.
Stars: ✭ 1,502 (+1151.67%)
Mutual labels:  annotations
Ibase4j
Spring,SpringBoot 2.0,SpringMVC,Mybatis,mybatis-plus,motan/dubbo分布式,Redis缓存,Shiro权限管理,Spring-Session单点登录,Quartz分布式集群调度,Restful服务,QQ/微信登录,App token登录,微信/支付宝支付;日期转换、数据类型转换、序列化、汉字转拼音、身份证号码验证、数字转人民币、发送短信、发送邮件、加密解密、图片处理、excel导入导出、FTP/SFTP/fastDFS上传下载、二维码、XML读写、高精度计算、系统配置工具类等等。
Stars: ✭ 1,548 (+1190%)
Mutual labels:  spring-mvc
Cli Spring Boot Scaffold
command line for generate crud and configs for spring boot projects
Stars: ✭ 113 (-5.83%)
Mutual labels:  spring-mvc

⚠️ tl;dr: don't use this repository, use something like Quarkus instead. ⚠️

Unfortunately, this project relies on an old version of Vert.x. Upgrading it to Vert.x 3.5 requires a lot of work, I am looking at it, but since it's a "weekend" project, it might take months. Sorry for the inconvenience. Obviously any kind of help would be greatly appreciated. Thank you for your comprehension.

If you feel like you want to help, any pull request would be highly welcomed. You can also fork the project, and start working on your own stuff, with your own vision of what such an annotation framework would be to suit your needs. The license allows you to do so.

You can start by forking the project, changing Vert.x dependency to 3.5 get it to compile (which requires some work) then run the tests (there's a pretty good code coverage) and start fixing stuff from there. That's probably the best way to help.

As an alternative, you can have a look at Quarkus, which adds JAX-RS annotation capabilities on top of Vert.x (with a lot of other interesting modules).

Special thanks to johnfg10 for upgrading to 3.5.2.


Build Status Codecov

Vert.x Nubes

Provides an annotation layer on top of vertx-web.

Declare your Vert.x routes with annotated methods and controllers, in a Spring MVC-ish way.

repositories {
  jcenter()
}

dependencies {
  compile 'com.github.aesteve:nubes:2.0'
}

Declarative

Nubes automatically injects method parameters at runtime so that you can express your routes in a declarative manner. By reading the signature of the method, you should be able to have a quick glimpse at what your route uses (query parameters, request body, ...) and produces (void => status 204, object => marshalled).

public PeanutsCharacter get(@Param CharacterType type) lets us know that the method uses a request parameter named type and that the response will contain a marshalled PeanutsCharacter POJO.

Nubes comes with a controller layer, but also a service layer. You can declare services as simple POJOS and they'll be injected within your controllers, you can also declare your services as async, they'll be started when your application starts, stopped when the application stops.

Extensible

The framework is designed to be fully extensible so that you can register and use your own annotations, whether it's an interceptor, a type-adapter, ...

A good example on how to extend the framework is Nubes Mongo, a set of additionnal utilities (annotations, interceptors, ...) designed to help you deal with Mongo on top of Nubes. For example, nubes-mongo registers a @Create annotation against Nubes framework, meaning that the result of the method should be saved against the Mongo database.

Basically, an annotation will be tied to a set of Vert.x's Handlers, executed before and/or after the 'route' method is executed.

Non-blocking (obviously) but also non-stumbling

Even though Nubes looks opinionated (declaring your routes in a single way : the controller/method way), keep in mind that at the end of the day, vertx-web's router is still there and fully accessible if you find yourself stuck in an edge case Nubes isn't designed to handle. This way, you should never, ever be stucked.

You just have a set of additional utilities at your disposal to declare your web routes in another way (a SpringMVC-ish way), to declare and inject services if you don't have a DI framework at your disposal, or to write Verticles differently.

The Router can also be injected as a field within your controllers as an easy way to deal with it, and maybe register routes at runtime if you need to.

Examples

(Work in Progress)

If you're interested in how a real-life project built with Nubes would look like, you can have a look at Nubes Chat a very simple chat relying on a REST API and Vert.x's event-bus bridge which shows both REST and Socket controllers in action. On top of that, it uses a MongoDB as a persistent store so you can get a nice view of the service layer.

Basic example :

A controller :

package com.peanuts.controllers;

@Controller("/peanuts")
public class PeanutsPages {
  
  public ENUM CharacterType {
    DOG, GIRL, BOY, BIRD;
  }
  
  @GET("/character")
  @View
  public String getCharacter(@ContextData Map<String, Object> data, @Param CharacterType type) {
    switch(type) {
      case DOG: 
        data.put("name", "Snoopy");
        break;
      case BOY:
        data.put("name", "Charlie Brown");
        break;
      // ...
    }
    return "character.hbs";
  }
}

The view :

web/views/character.hbs

<html>
  <body>
    Hello, I'm a Peanuts character, and my name is {{name}}
  </body>
</html>

GET "/peanuts/character?type=DOG" will return the following html view:

Hello, I'm a Peanuts character, and my name is Snoopy

A JSON api example

package com.peanuts.controllers;

@Controller("/api/1/peanuts")
@ContentType("application/json")
public class CharactersController {
  
  @Service("mongo")
  private MongoService mongo;
  
  @GET("/character")
  public PeanutsCharacter getCharacter(@Param CharacterType type) {
    switch(type) {
      case DOG: 
        return new PeanutsCharacter(CharacterType.DOG, "Snoopy", snoopysBirthDate);
      // etc. 
    }
  }
  
  @POST("/character") // declaring RoutingContext as parameter means your method is async
  public void createCharacter(RoutingContext context, @RequestBody PeanutsCharacter character) {
    mongo.save(character, handler -> {
      context.next();  
    }); // save it using JDBC service, mongo service, hibernate service, etc.
  }
}

With this an example of domain object :

package com.peanuts.model;

public class PeanutsCharacter {

  public ENUM CharacterType {
    DOG, GIRL, BOY, BIRD;
  }

  private CharacterType type;
  private String name;
  private Date birthDate;
  
  // getters, setters, constructors and stuff
}

GET "/api/1/peanuts/characters?type=DOG" with an Accept header containing application/json will return :

{
  "name":"Snoopy",
  "type":"DOG",
  "birthDate":"1950-11-04T08:00:00.000Z"
}

POST "/api/1/peanuts/characters" with the following request body :

{
  "name":"Snoopy",
  "type":"DOG",
  "birthDate":"1950-11-04T08:00:00.000Z"
}

Will save our favorite cartoon dog into the database, then return an HTTP 204.

How it works

VertxNubes as the entry point

The entry point of every work with the framwork is creatning a VertxNubes instance.

You'll notice the constructor takes two arguments :

  • a Vertx instance
  • a JsonObject containing the configuration

Please take a look at the configuration documentation for the available, mandatory or not, options.

Once you've created the VertxNubes instance, you need to bootstrap it. What it's gonna do is scanning your application classes (annotated with @Controller) in order to create the approriate Web routes/handlers and attach it to a vertx-web Router.

You can provide your own Router, if you want to to add custom routes and stuff in the standard vertx way.

You can also let VertxNubes instanciate a Router. It's gonna return it to you once it's done bootstrapping. And you'll be able to do pretty much whatever you need with it.

VertxNubes nubes = new VertxNubes(vertx, config);
nubes.bootstrap(res -> {
  if (res.succeeded()) {
    Router yourRouter = res.result();
    System.out.println("Everything's ready");
  } else {
    System.err.println("Something went wrong");
    res.cause().printStackTrace();
  }
});

You'll find a ton of examples in the tests of the project.

If you take a look at the mock controllers, you'll pretty much find everything that's possible to do with Nubes out of the box.

The Controller layer

What is a @Controller ?

A controller is a Java singleton (per Nubes instance) defining a set of methods which will be translated into vertx-web handlers. (~= express middlewares).

It's important that your controller defines a no-argument constructor, VertxNubes expect that.

In a controller you'll find routes, annotated with @GET, @POST, @PUT, ... but also filters of two differents types : @BeforeFilter and @AfterFilter.

For each route in your controller, before filters will be executed before your actual route method, and after filters, well... after.

Annotations

Nubes provides some default annotations. Here's the list.

But you can also define your own annotations, and attach vertx-web handlers to it.

In this case, you can register what Nubes calls "Annotation processors" which will be called before, after (or both) your method is invoked.

Nubes itself registers its own annotations using this API. For example, the @ContentType({"application/json", "application/xml"}) annotation is bound to a ContentTypeProcessor which will :

  • check the Accept header of the request, and if it doesn't matches the MIME type you're handling, return a 406 status to the client
  • find the most suitable MIME among the ones the client specified in its Accept header and the ones you specified in the body of the ContentType annotation
  • inject this ContentType as a variable in the RoutingContext so that you can also benefit from it
  • position the Content-Type response header so that you don't have to care about it

Read the annotations document

Parameters

Parameters are automatically injected into every method at runtime, depending on the context of the request (parameters, body, ...).

For a complete list of available parameters (by default), see the parameters documentation.

But you can also register your own parameter resolvers by telling nubes : "When you find this type of parameter, resolve it like this".

Parameters can be resolved simply by their types (that's how Nubes injects the RoutingContext or the EventBus parameters if your method asks for it) or by a custom annotation you define.

Read the parameters injection documentation

The View Layer

TODO : explain that template engines are created by the user, and bound to a file extension. Then how views are resolved, either by @View("viewName.extension") or through the ViewResolver parameter.

The Service Layer

Services in Nubes are simple POJOs you register on the Nubes instance using nubes.registerService(String name, Object serviceInstance). This way, you'll be able to access them from your controllers using the @Service("someName") annotation.

Standard services

Any POJO can be a service. Simply register it against Nubes.

Async services

In some case, services take time to startup or to be closed. If you want your service to be started when Nubes bootstraps, just implements Nubes Service interface and register it, the same way you would register a POJO.

RPC and service proxies

TODO : Explain how to use vertx's service proxy.

SockJS

Nubes provides a simple way to declare SockJS handlers with annotations instead of handlers defined in vertx-web.

For example, to handle incoming sockets you would do the following.

@SockJS("/sockjs/*")
public class SockJSController {
  @OnMessage
  public void onMessage(SockJSSocket emitter, Buffer message) {
    emitter.write(Buffer.buffer(message)); // simply echo the message back
  }
}

You can also use vertx-web's event-bus bridge if you want your users to access some addresses over the event-bus from client-side using SockJS.

@EventBusBridge("/sockjs/*")
@InboundPermitted("some-allowed-address")
public class BridgeController {

  @SOCKET_CREATED
  public void whenSocketIsCreated(BridgeEvent event) {
    // do what you want...
  }
  
  @REGISTER
  public void whenSomeUserRegisters(BridgeEvent event) {
    // do what you want...
  }
  
}
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].