美文网首页
在Spring Boot中整合Katharsis,来快速开发JS

在Spring Boot中整合Katharsis,来快速开发JS

作者: 南瓜慢说 | 来源:发表于2023-02-03 00:07 被阅读0次

    1 简介

    我们进行Web API开发的时候,经常会使用Json格式的消息体,而Json格式非常灵活,不同的人会有不同的设计风格和实现,而JSON API提供了一套标准。但它并不提供直接实现。

    Katharsis是JSON API的Java实现,使用它可以快速开发出Json based的Web接口,还能快速的整合到Spring中。今天我们就来试试如何在Spring Boot中使用Katharsis。

    2 整合过程

    2.1 添加依赖

    我们在Spring Boot中添加依赖如下,包括常规的starter、jpa和h2,而整合Katharsis只需要katharsis-spring即可。

    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
      </dependency>
      <dependency>
        <groupId>io.katharsis</groupId>
        <artifactId>katharsis-spring</artifactId>
        <version>3.0.2</version>
      </dependency>
    </dependencies>
    

    2.2 Entity类

    我们定义两个Entity,一个是学生,一个是教室,而教室对象会包含多个学生。

    学生:

    @JsonApiResource(type = "students")
    @Entity
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student {
        @JsonApiId
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        private String name;
    }
    

    教室:

    @JsonApiResource(type = "classrooms")
    @Entity
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class Classroom {
        @JsonApiId
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        private String name;
    
        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(name = "classrooms_students", joinColumns = @JoinColumn(name = "classroom_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"))
        @JsonApiRelation(serialize= SerializeType.EAGER)
        private Set<Student> students;
    }
    

    注解JsonApiResource这个会指定资源名称,这个会影响api的URL,注解JsonApiId则指定资源的id。

    2.3 资源操作类

    Katharsis使用ResourceRepository来对资源进行增删改查操作,这个跟数据库的增删改查类似,但属于更高一层。抽象到资源RESTful的资源层面,然后再调用数据库的Repository来操作,这里统一实现ResourceRepositoryV2接口。

    @Component
    public class StudentResourceRepository implements ResourceRepositoryV2<Student, Long> {
    
        private final StudentRepository studentRepository;
    
        public StudentResourceRepository(StudentRepository studentRepository) {
            this.studentRepository = studentRepository;
        }
    
        @Override
        public Student findOne(Long id, QuerySpec querySpec) {
            Optional<Student> student = studentRepository.findById(id);
            return student.orElse(null);
        }
    
        @Override
        public ResourceList<Student> findAll(QuerySpec querySpec) {
            return querySpec.apply(studentRepository.findAll());
        }
    
        @Override
        public ResourceList<Student> findAll(Iterable<Long> ids, QuerySpec querySpec) {
            return querySpec.apply(studentRepository.findAllById(ids));
        }
    
        @Override
        public <S extends Student> S save(S entity) {
            return studentRepository.save(entity);
        }
    
        @Override
        public void delete(Long id) {
            studentRepository.deleteById(id);
        }
    
        @Override
        public Class<Student> getResourceClass() {
            return Student.class;
        }
    
        @Override
        public <S extends Student> S create(S entity) {
            return save(entity);
        }
    
    }
    

    而数据库方面我们使用JPA实现即可:

    public interface StudentRepository extends JpaRepository<Student, Long> {
    }
    

    上面的代码是针对Student资源类型的,对Classroom类似,就不把代码列出来了。

    2.4 配置

    为了使用Katharsis,我们需要在配置中引入KatharsisConfigV3,我们直接在Spring Boot启动类中引入即可:

    @SpringBootApplication
    @Import(KatharsisConfigV3.class)
    public class KatharsisExample {
        public static void main(String[] args) {
            SpringApplication.run(KatharsisExample.class, args);
        }
    }
    

    Spring Boot的配置文件如下:

    server.port=8080
    server.servlet.context-path=/
    
    katharsis.domainName=https://www.pkslow.com
    katharsis.pathPrefix=/api/katharsis
    
    spring.datasource.url = jdbc:h2:mem:springKatharsis;DB_CLOSE_DELAY=-1
    spring.datasource.username = sa
    spring.datasource.password =
    
    spring.jpa.show-sql = true
    spring.jpa.hibernate.ddl-auto = create-drop
    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
    spring.jpa.properties.hibernate.globally_quoted_identifiers=true
    

    katharsis.pathPrefix是URL前缀,而katharsis.domainName会影响Self Link等返回。

    2.5 初始化数据

    为了方便测试,初始化一些数据进行查询:

    @Component
    public class InitData {
    
        private final ClassroomRepository classroomRepository;
    
        private final StudentRepository studentRepository;
    
        public InitData(ClassroomRepository classroomRepository, StudentRepository studentRepository) {
            this.classroomRepository = classroomRepository;
            this.studentRepository = studentRepository;
        }
    
        @PostConstruct
        private void setupData() {
            Set<Student> students = new HashSet<>();
            Student student = Student.builder().name("Larry Deng").build();
            students.add(student);
            studentRepository.save(student);
            student = Student.builder().name("Eason").build();
            students.add(student);
            studentRepository.save(student);
            student = Student.builder().name("JJ Lin").build();
            students.add(student);
            studentRepository.save(student);
    
            Classroom classroom = Classroom.builder().name("Classroom No.1").students(students)
                    .build();
            classroomRepository.save(classroom);
        }
    }
    

    至此则整合完毕了。

    3 测试

    整合完后启动,就可以用curl或Postman开始测试了:

    查询一个student:

    $ curl http://localhost:8080/api/katharsis/students/1 | jq .
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   139    0   139    0     0   9828      0 --:--:-- --:--:-- --:--:-- 23166
    {
      "data": {
        "id": "1",
        "type": "students",
        "attributes": {
          "name": "Larry Deng"
        },
        "links": {
          "self": "https://www.pkslow.com/api/katharsis/students/1"
        }
      }
    }
    

    查询多个student:

    $ curl http://localhost:8080/api/katharsis/students | jq .
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   429    0   429    0     0   3633      0 --:--:-- --:--:-- --:--:--  3830
    {
      "data": [
        {
          "id": "1",
          "type": "students",
          "attributes": {
            "name": "Larry Deng"
          },
          "links": {
            "self": "https://www.pkslow.com/api/katharsis/students/1"
          }
        },
        {
          "id": "2",
          "type": "students",
          "attributes": {
            "name": "Eason"
          },
          "links": {
            "self": "https://www.pkslow.com/api/katharsis/students/2"
          }
        },
        {
          "id": "3",
          "type": "students",
          "attributes": {
            "name": "JJ Lin"
          },
          "links": {
            "self": "https://www.pkslow.com/api/katharsis/students/3"
          }
        }
      ],
      "meta": {
        "totalResourceCount": null
      }
    }
    

    查询一个教室:

    $ curl http://localhost:8080/api/katharsis/classrooms/4 | jq .
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   834    0   834    0     0  62462      0 --:--:-- --:--:-- --:--:--  116k
    {
      "data": {
        "id": "4",
        "type": "classrooms",
        "attributes": {
          "name": "Classroom No.1"
        },
        "relationships": {
          "students": {
            "data": [
              {
                "id": "3",
                "type": "students"
              },
              {
                "id": "2",
                "type": "students"
              },
              {
                "id": "1",
                "type": "students"
              }
            ],
            "links": {
              "self": "https://www.pkslow.com/api/katharsis/classrooms/4/relationships/students",
              "related": "https://www.pkslow.com/api/katharsis/classrooms/4/students"
            }
          }
        },
        "links": {
          "self": "https://www.pkslow.com/api/katharsis/classrooms/4"
        }
      },
      "included": [
        {
          "id": "1",
          "type": "students",
          "attributes": {
            "name": "Larry Deng"
          },
          "links": {
            "self": "https://www.pkslow.com/api/katharsis/students/1"
          }
        },
        {
          "id": "2",
          "type": "students",
          "attributes": {
            "name": "Eason"
          },
          "links": {
            "self": "https://www.pkslow.com/api/katharsis/students/2"
          }
        },
        {
          "id": "3",
          "type": "students",
          "attributes": {
            "name": "JJ Lin"
          },
          "links": {
            "self": "https://www.pkslow.com/api/katharsis/students/3"
          }
        }
      ]
    }
    

    新增一个学生:

    $ curl --header "Content-Type: application/json"   --request POST   --data '{
        "data": {
            "type": "students",
            "attributes": {
                "name": "Justin"
            }
        }
    }'   http://localhost:8080/api/katharsis/students | jq .
    
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   249    0   135  100   114  11202   9459 --:--:-- --:--:-- --:--:-- 41500
    {
      "data": {
        "id": "6",
        "type": "students",
        "attributes": {
          "name": "Justin"
        },
        "links": {
          "self": "https://www.pkslow.com/api/katharsis/students/6"
        }
      }
    }
    

    修改:

    $ curl --header "Content-Type: application/json"   --request PATCH   --data '{
        "data": {
            "id":"6",
            "type": "students",
            "attributes": {
                "name": "Justin Wu"
            }
        }
    }'   http://localhost:8080/api/katharsis/students/6 | jq .
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   273    0   138  100   135   4425   4329 --:--:-- --:--:-- --:--:-- 10920
    {
      "data": {
        "id": "6",
        "type": "students",
        "attributes": {
          "name": "Justin Wu"
        },
        "links": {
          "self": "https://www.pkslow.com/api/katharsis/students/6"
        }
      }
    }
    

    删除:

    $ curl --header "Content-Type: application/json"   --request DELETE   --data '{
        "data": {
            "id":"6",
            "type": "students",
            "attributes": {
                "name": "Justin Wu"
            }
        }
    }'   http://localhost:8080/api/katharsis/students/6 | jq .
    

    至此,我们已经覆盖了增删改查操作了。而我们在代码中并没有去写我们之前常写的Controller,却可以访问对应接口。因为Katharsis默认已经帮我们实现了,可以查看类:io.katharsis.core.internal.dispatcher.ControllerRegistry

    4 代码

    代码请看GitHub: https://github.com/LarryDpk/pkslow-samples

    相关文章

      网友评论

          本文标题:在Spring Boot中整合Katharsis,来快速开发JS

          本文链接:https://www.haomeiwen.com/subject/ljwghdtx.html