Рубрики
Без рубрики

Создание микросервисов REST с помощью Javalin

Узнайте, как реализовать API REST с помощью фреймворка Javelin

Автор оригинала: Christopher Franklin.

1. введение

Javelin – это легкий веб-фреймворк, написанный для Java и Kotlin. Он написан поверх веб-сервера Jetty, что делает его очень производительным. Javalin смоделирован близко от koa.js , что означает, что он написан с нуля, чтобы быть простым для понимания и развития.

В этом уроке мы рассмотрим этапы создания базового микросервиса REST с использованием этого легкого фреймворка.

2. Добавление Зависимостей

Чтобы создать базовое приложение, нам нужна только одна зависимость – сам Javalin:


    io.javalin
    javalin
    1.6.1

Текущую версию можно найти здесь .

3. Настройка Javelin

Javelin упрощает настройку базового приложения. Мы начнем с определения нашего основного класса и настройки простого приложения “Hello World”.

Давайте создадим новый файл в нашем базовом пакете под названием JavalinApp.java .

Внутри этого файла мы создаем основной метод и добавляем следующее, чтобы настроить базовое приложение:

Javalin app = Javalin.create()
  .port(7000)
  .start();
app.get("/hello", ctx -> ctx.html("Hello, Javalin!"));

Мы создаем новый экземпляр Javalin, заставляем его прослушивать порт 7000, а затем запускаем приложение.

Мы также настраиваем нашу первую конечную точку, прослушивающую запрос GET в конечной точке/ hello .

Давайте запустим это приложение и посетим http://localhost:7000/hello чтобы увидеть результаты.

4. Создание пользовательского контроллера

Пример “Hello World” отлично подходит для введения темы, но он не полезен для реального приложения. Теперь давайте рассмотрим более реалистичный вариант использования Javelin.

Во-первых, нам нужно создать модель объекта, с которым мы работаем. Мы начинаем с создания пакета с именем user в корневом проекте.

Затем мы добавляем новый класс User :

public class User {
    public final int id;
    public final String name;

    // constructors
}

Кроме того, нам нужно настроить наш объект доступа к данным (DAO). В этом примере мы будем использовать объект в памяти для хранения наших пользователей.

Мы создаем новый класс в user packaged под названием UserDao.java:

class UserDao {

    private List users = Arrays.asList(
      new User(0, "Steve Rogers"),
      new User(1, "Tony Stark"),
      new User(2, "Carol Danvers")
    );

    private static UserDao userDao = null;

    private UserDao() {
    }

    static UserDao instance() {
        if (userDao == null) {
            userDao = new UserDao();
        }
        return userDao;
    }

    Optional getUserById(int id) {
        return users.stream()
          .filter(u -> u.id == id)
          .findAny();
    }

    Iterable getAllUsernames() {
        return users.stream()
          .map(user -> user.name)
          .collect(Collectors.toList());
    }
}

Реализация нашего DAO в виде синглтона упрощает его использование в примере. Мы также могли бы объявить его статическим членом нашего основного класса или использовать инъекцию зависимостей из библиотеки, такой как Guice, если бы захотели.

Наконец, мы хотим создать наш класс контроллера. Javalin позволяет нам быть очень гибкими, когда мы объявляем наши обработчики маршрутов, так что это только один из способов их определения.

Мы создаем новый класс под названием UserController.java в пользовательском пакете:

public class UserController {
    public static Handler fetchAllUsernames = ctx -> {
        UserDao dao = UserDao.instance();
        Iterable allUsers = dao.getAllUsernames();
        ctx.json(allUsers);
    };

    public static Handler fetchById = ctx -> {
        int id = Integer.parseInt(Objects.requireNonNull(ctx.param("id")));
        UserDao dao = UserDao.instance();
        User user = dao.getUserById(id);
        if (user == null) {
            ctx.html("Not Found");
        } else {
            ctx.json(user);
        }
    };
}

Объявляя обработчики статическими, мы гарантируем, что сам контроллер не содержит состояния. Но в более сложных приложениях мы можем захотеть сохранить состояние между запросами, и в этом случае нам нужно будет удалить статический модификатор.

Также обратите внимание, что модульное тестирование сложнее со статическими методами, поэтому, если мы хотим получить такой уровень тестирования, нам нужно будет использовать нестатические методы.

5. Добавление маршрутов

Теперь у нас есть несколько способов извлечения данных из нашей модели. Последний шаг-предоставить эти данные через конечные точки REST. Нам нужно зарегистрировать два новых маршрута в нашем главном приложении.

Давайте добавим их в наш основной класс приложений:

app.get("/users", UserController.fetchAllUsernames);
app.get("/users/:id", UserController.fetchById);

После компиляции и запуска приложения мы можем сделать запрос к каждой из этих новых конечных точек. Вызов http://localhost:7000/users будет список всех пользователей и вызывающих http://localhost:7000/users/0 получит однопользовательский объект JSON с идентификатором 0. Теперь у нас есть микросервис, который позволяет нам извлекать Пользовательские данные.

6. Расширение маршрутов

Извлечение данных является жизненно важной задачей большинства микросервисов.

Однако мы также должны иметь возможность хранить данные в нашем хранилище данных. Javelin предоставляет полный набор обработчиков путей, необходимых для создания служб.

Мы видели пример GET выше, но PATCH, POST, DELETE, и PUT также возможны.

Кроме того, если мы включим Джексона в качестве зависимости, мы сможем автоматически анализировать тела запросов JSON в наши классы моделей. Например:

app.post("/") { ctx ->
  User user = ctx.bodyAsClass(User.class);
}

это позволило бы нам захватить объект JSON User из тела запроса и перевести его в объект User model.

7. Заключение

Мы можем объединить все эти методы, чтобы создать наш микросервис.

В этой статье мы рассмотрели, как настроить Javelin и создать простое приложение. Мы также говорили о том, как использовать различные типы методов HTTP, чтобы клиенты могли взаимодействовать с нашим сервисом.

Для получения более подробных примеров использования Javelin обязательно ознакомьтесь с документацией /.

Кроме того, как всегда, код можно найти на GitHub .