๐๏ธ Java backend template of Vert.x
This application was generated using http://start.vertx.io
./mvnw clean test
./mvnw clean package
Run the source directly:
./mvnw clean compile exec:java
Run executable JAR file:
java -jar xxx-<version>-fat.jar
More configurations can be added into conf/config.json
in JSON format. The key of JSON object is named as xx.xx.xx.xx
which can be used for categorization.
The configuration will be loaded by LauncherVerticle and passed as parameter to MainVerticle. Then, MainVerticle is able to get configuration object by AbstractVerticle.config()
.
The configuration component is implemented by Vert.x Config, which supports listening to configuration changes and runtime hot-reloading. Once the backend detects modification of the configuration file, it will undeploy the current MainVerticle and deploy another MainVerticle based on the new configuration.
Apache Log4J 2 is used as logging backend in this template. The initialization code follows Vert.x Core's suggestions and completes the connection between Vert.x and Log4J2. The configuration file of logger is placed as log4j2.xml
under resource path and is free to customize. The usage of logger is to declare a Logger in each class and free to log anything:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
private static final Logger logger = LogManager.getLogger(Foo.class);
logger.info("Hello world!");
Vert.x Web is used to implement web component. All of the handler functions should be registered to a Vert.x Web Router, and the router will be bind to a Vert.x HTTP Server. The initialization code loads server configurations like listening port from configuration (conf/config.json
), and initialize the web router. Finally, it starts the server with the web router and server configurations.
HTTPS is supported by a HTTP server option. If enabled, the file path of public key certificate and private key should be provided in the configuration file.
For handling HTTP requests, the template defines the EndPoint
annotation to configure each API end point handler. The end point information includes:
- URL path of the end point
- End point version
- HTTP request type to access the end point
- Whether accessing this end point needs authentication
- Whether handler function needs to execute blocking function (because we cannot block Vert.x's eventloop)
The AbstractHandler is defined to handle the common logic like end point initialization. When extending a new handler, just write a class which extends AbstractHandler class and override handle()
function. Remember to configure end point information with EndPoint
annotation:
@EndPoint(
path = "/status",
version = "0.0.1",
methods = {"GET", "POST"},
jwtAuth = false,
block = false
)
public class StatusHandler extends AbstractHttpHandler {
@Override
protected void handle(RoutingContext ctx) {
endRequestWithMessage(ctx, 200, "API status ok.");
}
}
JSON Web Token authentication is supported with the help of Vert.x JWT Auth Provider. A JWT provider instance is initialized with file path of public key certificate and private key, which can be configured in conf/config.json
. Then, the provider instance can be used globally for generating or verifying tokens:
public static JWTAuth tokenProvider;
public static String generateToken(JsonObject param) {
return tokenProvider.generateToken(param,
new JWTOptions()
.setAlgorithm("RS256")
.setExpiresInMinutes(60)
);
}
public static Future<User> authenticate(String token) {
return tokenProvider.authenticate(
new JsonObject().put("token", token)
);
}
Vert.x provides more authentication methods like OAuth2. Extension can be done in a similar way like JWT.
Currently, only MySQL client is supported with the help of Vert.x MySQL Client. The instance of MySQL client is initialized when the backend starts up, with connect options and pool options of MySQL server from conf/config.json
. Then, the MySQL client can be used globally for queries, as well as transactions.
/* instance */
public static MySQLPool mysqlClient;
/* configurations */
MySQLConnectOptions connectOptions = new MySQLConnectOptions()
.setHost (config.getString ("mysql.host"))
.setPort (config.getInteger("mysql.port"))
.setUser (config.getString ("mysql.user"))
.setPassword (config.getString ("mysql.password"))
.setDatabase (config.getString ("mysql.db"))
.setConnectTimeout(config.getInteger("mysql.timeout.second") * 1000);
PoolOptions poolOptions = new PoolOptions()
.setMaxSize(config.getInteger("mysql.pool.size"));
/* initialization */
mysqlClient = MySQLPool.pool(vertx, connectOptions, poolOptions);
/* query */
mysqlClient
.query("SELECT COUNT(*) FROM table;")
.execute()
.compose(rows -> {
logQueryRowCount(rows);
return Future.succeededFuture();
});
More DBMS clients can be extended in a similar way, as long as Vert.x supports: PostgreSQL, MongoDB, Redis, DB2, ...
Copyright ยฉ 2021 Jingtang Zhang (Apache License 2.0)