Spring WebFlux 基础教程:构建简单RESTful API

我们通过使用 Spring WebFlux 来实现对 Person 对象操作的 RESTful API。
主要有 3 步操作:

  1. 实体的定义
  2. 实体的相关操作
  3. 路由规则的配置

定义 Person 实体

public class Person {

  private Integer age;

  private String name;

  public Person(String name, Integer age) {
    this.age = age;
    this.name = name;
  }

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return "Person{" +
        "age=" + age +
        ", name='" + name + '\'' +
        '}';
  }
}

使用内存Map, 模拟数据存储 

public interface PersonRepository {

  Mono<Person> getPerson(int id);

  Flux<Person> allPeople();

  Mono<Void> savePerson(Mono<Person> personMono);

  Mono<Void> deletePerson(int id);

  Mono<Void> updatePerson(int id, Mono<Person> personMono);
}

实体操作

@Slf4j
public class DummyPersonRepository implements PersonRepository {

  private final Map<Integer, Person> people = new ConcurrentHashMap<>();

  public DummyPersonRepository() {
    this.people.put(1, new Person("John Doe", 42));
    this.people.put(2, new Person("Jane Doe", 36));
  }

  @Override
  public Mono<Person> getPerson(int id) {
    return Mono.justOrEmpty(this.people.get(id));
  }

  @Override
  public Flux<Person> allPeople() {
    return Flux.fromIterable(this.people.values());
  }

  @Override
  public Mono<Void> savePerson(Mono<Person> personMono) {
    return personMono.doOnNext(person -> {
      int id = this.people.size() + 1;
      this.people.put(id, person);
      log.info("Save id = {}, person = {}", id, person);
    }).then(Mono.empty());
  }

  @Override
  public Mono<Void> deletePerson(int id) {
    this.people.remove(id);
    return Mono.empty();
  }

  @Override
  public Mono<Void> updatePerson(int id, Mono<Person> personMono) {
    return personMono.doOnNext(person -> {
      this.people.put(id, person);
      log.info("Update id = {}, person = {}", id, person);
    }).then(Mono.empty());
  }
}

Handler 处理

public class PersonHandler {

  private final PersonRepository repository;

  public PersonHandler(PersonRepository repository) {
    this.repository = repository;
  }

  public Mono<ServerResponse> getPerson(ServerRequest request) {
    int personId = Integer.parseInt(request.pathVariable("id"));
    Mono<Person> personMono = this.repository.getPerson(personId);
    return personMono.flatMap(person -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
        .body(BodyInserters.fromValue(person))).switchIfEmpty(ServerResponse.notFound().build());
  }

  public Mono<ServerResponse> savePerson(ServerRequest request) {
    Mono<Person> personMono = request.bodyToMono(Person.class);
    return ServerResponse.ok().build(this.repository.savePerson(personMono));
  }

  public Mono<ServerResponse> allPeople(ServerRequest request) {
    Flux<Person> personFlux = this.repository.allPeople();
    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(personFlux, Person.class);
  }

  public Mono<ServerResponse> deletePerson(ServerRequest request) {
    int id = Integer.parseInt(request.pathVariable("id"));
    return ServerResponse.ok().build(this.repository.deletePerson(id));
  }

  public Mono<ServerResponse> updatePerson(ServerRequest request) {
    int personId = Integer.parseInt(request.pathVariable("id"));
    Mono<Person> personMono = request.bodyToMono(Person.class);
    return ServerResponse.ok().build(this.repository.updatePerson(personId, personMono));
  }
}

路由规则配置

@Configuration
public class RoutingConfiguration {

  @Bean
  public PersonRepository repository() {
    return new DummyPersonRepository();
  }

  @Bean
  public PersonHandler handler(PersonRepository repository) {
    return new PersonHandler(repository);
  }

  @Bean
  public RouterFunction<ServerResponse> routes(PersonHandler handler) {
    return RouterFunctions.route().GET("/person/{id}",
        RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::getPerson)
        .GET("/person", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::allPeople)
        .POST("/person", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::savePerson)
        .DELETE("/person/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::deletePerson)
        .PUT("/person/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::updatePerson)
        .build();
  }
}

测试效果

1.GET 方法,请求所有的 Person 对象。

2.GET 方法,请求单个 Person 对象。

3.POST 方法,增加一个 Person。

4.DELETE 方法,删除一个Person。

5.PUT方法,更新一个 Person。

至此,一个简单的 RESTful 项目构建完成了。

posted @ 2021-07-28 22:47  lzyer  阅读(323)  评论(0编辑  收藏  举报