Cloudopt Next is a very lightweight, modern, kotlin-based, full-stack development framework that supports both Java and Kotlin. You can handle Url parsing, data encapsulation, Json output, and more, radically reducing development time and improving development experience.
You can directly change the version number of maven dependencies:
<dependency>
<groupId>net.cloudopt.next</groupId>
<artifactId>cloudopt-next-web</artifactId>
<version>3.0.0.1 - RELEASE</version>
</dependency>
Copy the code
Version 3.0 begins with JDK 11 and above, Kotlin 1.5 and above, vert.x 4 and above.
If you want to learn more, head over to the website or GitHub.
The core changes
Full support for Kotlin coroutines
Currently, Interceptor, Validator, Route, and WebSocket support coroutines (suspend and await). Handler is not intended to be supported, mainly because there are a lot of places involved in the Handler, basically every step of the Handler, in theory should not put blocking, long processing code, more suitable for things like logging, etc. If you need to use blocking code, it is recommended to use the following methods that specifically run blocking code. Based on vert. x + Kotlin, seven coroutine writing methods are implemented:
For example, if you need to run some blocked code and pass the result back, you can run it as follows. Of course you can also run blocked code through worker. Worker. Remember to pass the result through handler.plete at the end, otherwise you’ll be stuck waiting forever.
fun test(a) {
var id = worker<Int>({ handler ->
handler.complete(1)
}, { asyncResult ->
//onComplete})}Copy the code
The second option is to use the await property of Kotlin’s coroutines, which is more elegant to write. However, using a Kotlin coroutine requires you to declare suspend on the method. This is also the recommended asynchronous writing.
suspend fun test(a) {
var id = await<Int> { handler ->
handler.complete(1)}}Copy the code
The third case is when you use await syntax where the suspend syntax is not supported. You can run it as follows:
fun test(a) {
global {
var id = await<Int> { handler ->
handler.complete(1)}}}Copy the code
The Global syntax is essentially using Kotlin’s GlobalScope and automatically configuring NextServer’s Vertx coroutine object into it.
Although the suspend declaration is used, kotlin’s language specification requires that all call superiors declare it. Essentially, the first argument to suspend after compilation is passing a coroutine object, so you must declare it level by level so that the bottom-most method can reach the suspend object.
In some cases, however, the suspend syntax is not recognized, so you need another way to put coroutine objects in it.
Using global{} syntax sugar wrap, verTX coroutine objects are automatically passed down. Then the parent method does not need to declare suspend.
Fourth, you can add an @blocking annotation to the routing method to make it automatically a synchronous, Blocking route.
@Blocking
@GET("blocking")
fun blocking(a) {
renderText("This is Blocking!")}Copy the code
Fifth, if you want to run code for more than 10 seconds, do not use any of the above methods and use the THEN syntax instead.
The syntax sugar of then places wrapped code in a queue of context events, and is executed asynchronously after all queues in the context have been processed.
then{
println(1)}Copy the code
The sixth case is to return directly in await.
val text = await {
return@await "success"
}
Copy the code
The seventh case is to use the async method body when it is inconvenient to declare suspend.
private fun asyncFunction(a): String = async {
return@async await {
return@await "success"}}Copy the code
New plugins
All the plug-ins are redesigned by coroutine, reconstructing Redis and Cache plug-ins. Added ClickHouse, GRPC, Health, Polyglot plugins.
The new Redis plugin replaces Jedis with Lettuce, and supports using Next’s unique coroutine syntax to operate Redis with Lettuce methods.
var value = await<String>{handler->
handler.complete(RedisManager.sync().get("key"))}Copy the code
The new Cache plug-in comes with a distributed level 2 Cache. Efficient two-level distributed caching is implemented with Caffeine and Redis, which is reusable with the Redis plugin, and supports automatic yield caching using @cacheable.
@GET("cacheable/:id")
@Cacheable("testRegion", key = "@{url}-@{id}", keyGenerator = DefaultKeyGenerator::class, l2 = true)
fun cacheable(a) {
renderJson(json("name" to "cacheable"))}Copy the code
The gRPC plug-in brings gRPC support to Next. As long as the gRPC plug-in is loaded at startup, gRPC service listening can be directly started, and all plug-ins are shared with the Http service.
fun main(a) {
NextServer.addPlugin(GrpcPlugin())
NextServer.run()
}
Copy the code
The Health plug-in is a plug-in that helps you do Health checks and supports custom Health checks, check callbacks, and Json reports.
fun main(a) {
HealthChecksManager.register("disk", DiskSpaceHealthIndicator())
HealthChecksManager.register("jvm", JvmHealthIndicator())
HealthChecksManager.register("system", SystemIndicator())
HealthChecksManager.registerHook("logger", LoggerHook())
NextServer.addPlugin(HealthChecksPlugin())
NextServer.run()
}
Copy the code
The Polyglot plugin provides GraalVM support for Next, which allows you to run Python, JavaScript, Ruby, R directly from Kotlin with GraalVM.
python {
"print('Hello Python! ')"
}
Copy the code
Method level interceptors
RouteHandler is now available in 3.0.0.0. Any annotation that declares @before or @after in the RouteHandler will declare the corresponding implementation handler class. The route will automatically implement an AOP-like interception mechanism based on whether it is Before or After.
More places support DSL
We have more places to provide support for Kotlin DSL, such as:
json(
"a" to "1"."b" to json(
"c" to "2"
),
"c" to jsonArray(
json(
"d" to "3")),"student" to Student(name = "next", sex = 1))Copy the code
There were also nearly 30+ feature updates and 120 + commits.
Get help and support
- Check the reference documentation for specific code examples or for frequently asked questions.
- If you encounter problems after upgrading the version, check the upgrade instructions in the Wiki.
- Send an email to [email protected].
- Please send an Issue to GitHub to submit your questions and we will answer them as soon as possible.
- If you are in China, you can also join the QQ group: 557692142.
The project address
- Official website: Next.cloudopt.net
- Making: github.com/cloudoptlab…
- gitee.com/cloudopt/cl…
Our other interesting research
Cloudopt AdBlocker Cloudopt AdBlocker is a browser extension based on AdguardBrowserExtension and Cloudopt’s own cloud reputation assessment technology. It protects you from tracking and malicious domain names in real time. Filter banner ads, pop-up ads, etc.
Baize is a machine learning-based privacy protection engine that runs directly in the browser and can effectively block tracking scripts and malicious advertising scripts. Developed using JavaScript, can run in Node.js, browser environment.
Pyencrypt-plus is a Python encryption library with a variety of common encryption algorithms and is extremely easy to use. All encryption algorithms are inherited from the unified abstract interface, so that it does not need to care about technical details, five minutes to get started.