BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Javalin: um framework web leve para Java e Kotlin

Javalin: um framework web leve para Java e Kotlin

O Javalin é um framework web leve para o Java e Kotlin, projetado para ser simples, que suporta websockets, HTTP2, e requisições assíncronas. O Javalin começou como um fork do framework SparkJava, mas rapidamente foi reescrito, influenciado pelo framework JavaScript koa.js.

O Javalin é construído em cima do Jetty e tem performance parecida com a do Jetty sem nenhuma aplicação. Além disso, os desenvolvedores não precisam estender nenhuma classe, usar @Annotations, ou mesmo baixar binários diferentes do framework para codificar em Java ou Kotlin.

Para iniciar com o Javalin em Java, os desenvolvedores somente precisam de um método public static void main conforme a abaixo:

public static void main(String[] args) {
    var app = Javalin.create().start(7000);
    app.get("/", ctx -> ctx.result("Hello World"));
}

Vamos dar uma olhada em um trecho de código com algumas configurações adicionais:

var app = Javalin.create(config -> {
    config.defaultContentType = "application/json";
    config.autogenerateEtags = true;
    config.addStaticFiles("/public");
    config.asyncRequestTimeout = 10_000L;
    config.dynamicGzip = true;
    config.enforceSsl = true;
}).routes(() -> {
    path("users", () -> {
        get(UserController::getAll);
        post(UserController::create);
        path(":user-id"(() -> {
            get(UserController::getOne);
            patch(UserController::update);
            delete(UserController::delete);
        });
        ws("events", userController::webSocketEvents);
    });
}).start(port);

É muito simples validar parâmetros tais como, path params, query params, e form params no Javalin:

var myQpStr = ctx.queryParam("my-qp"); // sem validação, retorna String ou null
var myQpInt = ctx.pathParam("my-qp", Integer.class).get(); // retorna um Integer ou lança exceção
var myQpInt = ctx.formParam("my-qp", Integer.class).check(i -> i > 4).get(); // Integer > 4

// valida dois query parameters dependentes:
var fromDate = ctx.queryParam("from", Instant.class).get();
var toDate = ctx.queryParam("to", Instant.class)
        .check(it -> it.isAfter(fromDate), "'to' tem que ser após 'from'")
        .get();

// valida um a corpo json:
var myObject = ctx.bodyValidator(MyObject.class)
        .check(obj -> obj.myObjectProperty == someValue)
        .get();

Outra funcionalidade interessante no Javalin que existe em outros frameworks são os Handlers. O Javalin traz before-handlers, endpoint-handlers, after-handlers, exception-handlers e error-handlers.

//before handlers
app.before(ctx -> {
    // executa antes de todas requests
});
app.before("/path/*", ctx -> {
    // executa antes da request /path/*
});

//endpoint handlers
app.get("/", ctx -> {
    ctx.json(object);
});

app.get("/hello/*, ctx -> {
    // captura todas requests para o sub-paths de /hello/
});

//after handlers
app.after(ctx -> {
    // executa após todas requests
});
app.after("/path/*", ctx -> {
    // executa após a request /path/*
});

Para lidar com autenticação/autorização, o Javalin traz a interface funcional AccessManager, na qual os desenvolvedores podem implementar seus próprios controles de acesso da maneira que preferirem.

// ajusta o controle de acesso que o Javalin deve usar
app.accessManager((handler, ctx, permittedRoles) -> {
    MyRole userRole = getUserRole(ctx);
    if (permittedRoles.contains(userRole)) {
        handler.handle(ctx);
    } else {
        ctx.status(401).result("Unauthorized");
    }
});

Role getUserRole(Context ctx) {
}

enum MyRole implements Role {
    ANYONE, ROLE_ONE, ROLE_TWO, ROLE_THREE;
}

app.routes(() -> {
    get("/un-secured",   ctx -> ctx.result("Hello"),   roles(ANYONE));
    get("/secured",      ctx -> ctx.result("Hello"),   roles(ROLE_ONE));
});

Desde a versão 3.0, o Javalin também tem um plugin para o OpenAPI (Swagger). A implementação completa da especificação do OpenAPI 3.0 está disponível tanto como uma DSL e annotations.

OpenAPI DSL:

val addUserDocs = document()
        .body()
        .result("400")
        .result("204")

fun addUserHandler(ctx: Context) {
    val user = ctx.body()
    UserRepository.addUser(user)
    ctx.status(204)
}

OpenAPI annotations:

@OpenApi(
    requestBody = OpenApiRequestBody(User::class),
    responses = [
        OpenApiResponse("400", Unit::class),
        OpenApiResponse("201", Unit::class)
    ]
)
fun addUserHandler(ctx: Context) {
    val user = ctx.body()
    UserRepository.createUser(user)
    ctx.status(201)
}

Para publicar uma aplicação Javalin, os desenvolvedores somente precisam criar um jar com suas dependências (usando o maven-assembly-plugin), então executar o jar com java -jar filename.jar, o Javalin tem um servidor Jetty embutido, de forma que nenhum servidor de aplicação é necessário.

O Javalin também tem uma página dedicada para educadores, que enfatiza que os estudantes podem se beneficiar do Javalin, dado que não é necessário nenhum Servlet Container/Application Server, uma vez que o Jetty é embutido no Javalin.

Existem alguns tutoriais disponíveis, tais como Running on GraalVM, e Kotlin CRUD REST API, a lista completa de exemplos pode ser encontrada na página de tutoriais.

Maiores detalhes sobre o Javalin podem ser encontrados na página da documentação. É possível realizar o download do Javalin via maven ou manualmente através do maven central.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT