Практический опыт работы с REST API Dropwizard

автор vadim


Dropwizard — это REST-ориентированная среда, которая объединяет несколько пакетов Java в единое целое. Это альтернатива Spring (и пакету Spring WebMVC). Dropwizard обеспечивает более удобный интерфейс. По соглашению он принимает даже больше настроек, чем Spring, и исключает большую часть поверхности API, которая не связана конкретно с доставкой REST API.

Начать новый проект Dropwizard

Давайте начнем с создания нового проекта с использованием официального архетипа Dropwizard Maven. Найдите удобное место в вашей локальной системе и из командной строки введите команду из листинга 1.

Листинг 1. Запуск архетипа

mvn archetype:generate -DarchetypeGroupId=io.dropwizard.archetypes -DarchetypeArtifactId=java-simple -DarchetypeVersion=2.0.0

Это будет работать в интерактивном режиме. Я использовал идентификатор группы com.infoworld и идентификатор артефакта Demo. Я также использовал Demo в качестве имени.

Как только архетип завершит свое развертывание, вы сможете cd в свой каталог (в моем случае cd Demo). Теперь вы устанавливаете зависимости с помощью mvn clean package.

Теперь приложение можно запустить с помощью

java -jar target/Demo-1.0-SNAPSHOT.jar server 

(Не забудьте использовать имя приложения, которое вы ему дали, если оно отличается от Demo.)

Если вы сейчас посетите localhost:8080, вас встретит ошибка «не найдено» в формате JSON по умолчанию:

{"code":404,"message":"HTTP 404 Not Found"}

Сопоставить конечную точку

Пока что приложение возвращает только ошибки 404, поскольку конечные точки не сопоставлены. Я хочу дать вам четкое представление о том, как это достигается с помощью Dropwizard. Мы изолируем процесс, сопоставив конечную точку простой строки.

Шаг 1 — создать класс, который действует как обработчик пути. Помните, жизненное призвание Dropwizard — объединить несколько лучших в своем классе библиотек в простой в использовании пакет. Для поддержки конечных точек RESTful Dropwizard использует Jersey. В вашем приложении уже полностью настроен Джерси. Отображения путей выполняются с помощью синтаксиса Джерси.

Шаг 2 — зарегистрировать класс обработчика в приложении. Давайте сделаем эти два шага по очереди.

Создайте класс обработчика пути

По соглашению обработчики конечных точек Dropwizard находятся в папке /src/main/java/com/infoworld/resources (или в папке с любым идентификатором группы, который вы выберете). Мы собираемся добавить обработчик конечной точки для возврата списка авторов песен. Как видно из листинга 2, мы вернем только самое лучшее. Создайте новый файл SongWriters.java в каталоге /resources.

Листинг 2. Конечная точка SongWriters

package com.infoworld.resources;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.Optional;

@Path("/songwriters")
@Produces(MediaType.APPLICATION_JSON)
public class SongWriters {
    public SongWriters() {
    }

    @GET
    public String getBrands() {
        return "{'name':'Roger Waters','name':'Tom Petty'}";
    }
}

Листинг 2 довольно прост. Самому классу дается путь через @Path аннотацию, а JSON указывается в качестве типа носителя через @Produces аннотация. Далее, getBrands() метод, который возвращает строку, отображается в метод GET HTTP метод через @GET аннотация. Метод просто возвращает жестко закодированную строку, представляющую набор авторов песен.

Зарегистрируйте обработчик

Теперь зарегистрировам обработчик. Откройте файл /src/main/java/com/infoworld/DemoApplication.java и измените run() метод будет выглядеть как в листинге 3.

Листинг 3. Регистрация обработчика SongWriters

import com.infoworld.resources.SongWriters;
// ...
public void run(final DemoConfiguration configuration, final Environment environment) {
        SongWriters songWriters = new SongWriters();
        environment.jersey().register(songWriters);
    }

Опять же, довольно просто. В листинге 3 импортируется только что созданный класс, а затем используется метод Environment объект для доступа к Джерси и регистрации обработчика. Обратите внимание на run метод также получает DemoConfiguration объект, который вы вскоре увидите в действии.

Тестирование обработчика

Теперь, если вы посетите localhost:8080/songwriters, вы получите JSON, который вы жестко запрограммировали. Обратите внимание, что система легко обработала возврат строки в формате JSON.

Смоделируйте домен

Теперь вы хотите перейти от жестко закодированной строки к использованию реальных объектов предметной области. Начните с создания файла /src/main/java/com/infoworld/domain/SongWriter.java и передайте ему содержимое листинга 4.

Листинг 4. Класс модели предметной области SongWriter

package com.infoworld.domain;

import java.util.ArrayList;
import java.util.List;

public class SongWriter {
    private final String name;
    private List songs = new ArrayList<>();

    public SongWriter(final String name, final List songs) {
        this.name = name;
        this.songs = songs;
    }

    public String getName() {
      return name;
    }

    public List getSongs(){
      return this.songs;
    }
}

Добавить класс репозитория

Теперь мы добавим класс репозитория, который будет представлять уровень доступа к данным. Создайте новую папку и файл: /src/main/java/com/infoworld/repo/SongWriterRepo.java.

Листинг 5. Класс SongWriterRepo

package com.infoworld.repo;

import com.infoworld.domain.SongWriter;
import java.util.List;
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.Collectors;

public class SongWriterRepo {
  private final List songWriters;
  public SongWriterRepo(){
    this.songWriters = new ArrayList();     
  }

  public SongWriterRepo(List songWriters){
    this.songWriters = songWriters;
  }

  public List findAll(){
    return songWriters;
  }

  public Optional getByName(final String name){
    return songWriters.stream().filter(sw -> sw.getName().equals(name)).findFirst();
  }
}

Как видно из листинга 5, SongWriterRepo отвечает за возврат всех объектов SongWriter в файле. List через findAll() метод, в то время как getByName() Метод извлекает автора песен, указанного в имени строки.

Используйте слой домена

Теперь мы будем использовать новый слой для управления JSON, возвращаемым конечной точкой ресурса. Измените com.infoworld.resource.SongWriters, чтобы он выглядел как в листинге 6.

Листинг 6. Модифицированный класс SongWriters

package com.infoworld.resources;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.Optional;

import com.infoworld.repo.SongWriterRepo;
import com.infoworld.domain.SongWriter;

@Path("/songwriters")
@Produces(MediaType.APPLICATION_JSON)
public class SongWriters {
   private final SongWriterRepo repo;
    public SongWriters(SongWriterRepo repo) {
      this.repo = repo;
    }

    @GET
    public List getBrands() {
        return repo.findAll();
    }
}

В листинге 6 жестко запрограммированная строка исключена в пользу ссылки на SongWriterRepo класс, который устанавливается в конструкторе. Теперь взгляните на листинг 7, где эти классы объединены в DemoApplication сорт.

Листинг 7. Подключение доменного класса в DemoApplication

package com.infoworld;

import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;

import com.infoworld.resources.SongWriters;
import com.infoworld.repo.SongWriterRepo;

public class DemoApplication extends Application {
// ...
    @Override
    public void run(final DemoConfiguration configuration, final Environment environment) {
        SongWriterRepo swRepo = new SongWriterRepo();
        SongWriters songWriters = new SongWriters(swRepo);
        environment.jersey().register(songWriters);
    }
}

Вернуться в DemoApplication класс и измените его, как показано в листинге 7. Обратите внимание, что теперь вы создаете экземпляр SongWriterRepo объект и параметризовать SongWriters объект ресурса, прежде чем передать его Джерси.

Теперь, если вы пересоберете проект и посетите localhost:8080/songwriters, вы обнаружите пустой массив. Давайте добавим жестко запрограммированного автора песен, как показано в листинге 8.

Листинг 8. Добавление автора песен

public void run(final DW2Configuration configuration,
                    final Environment environment) {

        List preload = new ArrayList();
        preload.add(new SongWriter("Mark Knopfler", new ArrayList()));

        SongWriterRepo swRepo = new SongWriterRepo(preload);
        SongWriters songWriters = new SongWriters(swRepo);
        environment.jersey().register(songWriters);
    }

Теперь вы получите результат, когда достигнете конечной точки.

Используйте файл конфигурации

Добавьте новый файл конфигурации по адресу src/main/resources/Demo-Config.yml и поместите в него содержимое листинга 9.

Листинг 9. Конфигурация YAML

---
songWriters:
  - John Lennon
  - Jeff Lynne

Теперь измените файл com.infoworld.DemoConfiguration.java, чтобы он выглядел как в листинге 10. Этот файл используется для моделирования файла конфигурации через Jackson.

Листинг 10. Конфигурация Java

package com.infoworld;

import io.dropwizard.Configuration;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.*;
import javax.validation.constraints.*;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;
import java.util.ArrayList;

public class DW2Configuration extends Configuration {
  private List<String> songWriters;
  @JsonCreator
  public DW2Configuration(@JsonProperty("songWriters") List<String> songWriters){
          this.songWriters = songWriters;
  }
  public List<String> getSongWriters(){
          return this.songWriters;
  }
}

Теперь используйте файл в DemoApplicationкак показано в листинге 11.

Листинг 11. Использование файла конфигурации для предварительной загрузки авторов песен в DemoApplication.java

    @Override
    public void run(final DemoConfiguration configuration,
                    final Environment environment) {

        List preload = new ArrayList();

        configuration.getSongWriters().forEach(sw -> preload.add(new SongWriter(sw, new ArrayList())));
        SongWriterRepo swRepo = new SongWriterRepo(preload);
        SongWriters songWriters = new SongWriters(swRepo);
        environment.jersey().register(songWriters);
    }

Основная суть изменения в листинге 11 заключается в том, что файл конфигурации помещен в DemoConfiguration класс, заполняющий getSongWriters() метод, который используется для предварительной загрузки класса репозитория.

Запустите приложение с файлом конфигурации

Для запуска этого приложения с файлом конфигурации требуется небольшое изменение. Обратите внимание, что в листинге 12 ссылка на файл появляется после вызова server.

Листинг 12. Запуск приложения с файлом конфигурации

java -jar target/DW2-1.0-SNAPSHOT.jar server src/main/resources/DW2-config.yml

Теперь, когда вы зайдете в приложение по адресу localhost:8080/songwriters, вы увидите предварительно загруженных авторов песен.

Dropwizard — это экономичная альтернатива RESTful API на основе Spring. Как вы видели здесь, основное внимание уделяется предоставлению простого, но достаточного стека для удовлетворения этих требований.

Исходники демо-приложения доступны здесь.

Related Posts

Оставить комментарий