java - 如何使用 Swagger codegen 开发一个简单的 REST 客户端?

标签 java spring-boot swagger rest-client swagger-codegen

我正在学习 Swagger 以及如何使用 Swagger codegen 生成 REST 客户端。我知道如何用 Swagger 做文档,我也知道如何用 Swagger 生成一个简单的 REST 服务器,但我不知道如何用 Swagger codegen 生成一个简单的 REST 客户端。

例如,我有一个简单的应用程序,它是一个 REST 服务器,我想生成 REST 客户端。我可以用 Swagger codegen 做到这一点吗?

REST 服务器的 Controller :

package com.dgs.spring.springbootswagger.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

@RestController
@RequestMapping("/api/v1")
@Api(value = "Employee Management System", description = "Operations pertaining to employee in Employee Management System")
public class EmployeeController {

     @Autowired
     private EmployeeRepository employeeRepository;

        @ApiOperation(value = "View a list of available employees", response = List.class)
        @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Successfully retrieved list"),
            @ApiResponse(code = 401, message = "You are not authorized to view the resource"),
            @ApiResponse(code = 403, message = "Accessing the resource you were trying to reach is forbidden"),
            @ApiResponse(code = 404, message = "The resource you were trying to reach is not found")
        })
     @GetMapping("/employees")
     public List<Employee> getAllEmployees() {
         return employeeRepository.findAll();
     }

     @ApiOperation(value = "Get an employee by Id")   
     @GetMapping("/employees/{id}")
     public ResponseEntity<Employee> getEmployeeById(
             @ApiParam(value = "Employee id from which employee object will retrieve", required = true) @PathVariable(value = "id") Long employeeId)
             throws ResourceNotFoundException {

          Employee employee = employeeRepository.findById(employeeId)
            .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

          return ResponseEntity.ok().body(employee);
     }

     @ApiOperation(value = "Add an employee")
     @PostMapping("/employees")
     public Employee createEmployee(
             @ApiParam(value = "Employee object store in database table", required = true) @Valid @RequestBody Employee employee) {
         return employeeRepository.save(employee);
     }

     @ApiOperation(value = "Update an employee")
     @PutMapping("/employees/{id}")
     public ResponseEntity<Employee> updateEmployee(
             @ApiParam(value = "Employee Id to update employee object", required = true) @PathVariable(value = "id") Long employeeId,
             @ApiParam(value = "Update employee object", required = true) @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {

          Employee employee = employeeRepository.findById(employeeId)
            .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

          employee.setEmail(employeeDetails.getEmail());
          employee.setLastName(employeeDetails.getLastName());
          employee.setFirstName(employeeDetails.getFirstName());
          final Employee updatedEmployee = employeeRepository.save(employee);

          return ResponseEntity.ok(updatedEmployee);
     }

     @ApiOperation(value = "Delete an employee")
     @DeleteMapping("/employees/{id}")
     public Map<String, Boolean> deleteEmployee(
             @ApiParam(value = "Employee Id from which employee object will delete from database table", required = true) @PathVariable(value = "id") Long employeeId)
       throws ResourceNotFoundException {

      Employee employee = employeeRepository.findById(employeeId)
        .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

      employeeRepository.delete(employee);
      Map<String, Boolean> response = new HashMap<>();
      response.put("deleted", Boolean.TRUE);

      return response;
     }
}

之后我开发了一个简单的 REST 客户端:

package com.dgs.restclient.controllers;

@Controller
public class UpdateController {

    @Autowired
    private EmployeeRestClient restClient;

    @GetMapping("/showStartUpdate")
    public String showStartCheckin() {
        return "startUpdate";
    }

    @PostMapping("/startUpdate")
    public String startCheckIn(@RequestParam("employeeId") Long employeeId, ModelMap modelMap) {

        Employee employee = restClient.findEmployee(employeeId);
        modelMap.addAttribute("employee", employee);

        return "displayEmployeeDetails";
    }

    @PostMapping("/completeUpdate")
    public String completeCheckIn(@RequestParam("employeeId") Long employeeId,
            @RequestParam("employeeFirstName") String employeeFirstName,
            @RequestParam("employeeLastName") String employeeLastName,
            @RequestParam("employeeEmail") String employeeEmail) {

        EmployeeUpdateRequest employeeUpdateRequest = new EmployeeUpdateRequest();
        employeeUpdateRequest.setId(employeeId);
        employeeUpdateRequest.setFirstName(employeeFirstName);
        employeeUpdateRequest.setLastName(employeeLastName);
        employeeUpdateRequest.setEmail(employeeEmail);
        restClient.updateEmployee(employeeUpdateRequest);

        return "updateConfirmation";
    }

}

EmployeeRestClient:

package com.dgs.restclient.integration;

@Component
public class EmployeeRestClientImpl implements EmployeeRestClient {

    private static final String EMPLOYEE_REST_URL = 
            "http://localhost:8080/api/v1/employees/";

    @Override
    public Employee findEmployee(Long id) {

        RestTemplate restTemplate = new RestTemplate();
        Employee employee = restTemplate
                .getForObject(EMPLOYEE_REST_URL + id, Employee.class);

        return employee;
    }

    @Override
    public Employee updateEmployee(EmployeeUpdateRequest request) {

        RestTemplate restTemplate = new RestTemplate();
        restTemplate
                .put(EMPLOYEE_REST_URL + request.getId(), request, Employee.class); 

        Employee employee = restTemplate
                .getForObject(EMPLOYEE_REST_URL + request.getId(), Employee.class);

        return employee;
    }

}

这个 REST Client 是我开发的,我想知道我是否可以使用 Swagger codegen 进行这个 REST Client 开发,如何做?我只需要在 pom.xml 中添加 swagger-codegen-maven-plugin 吗?我听说过添加这个插件和一个 yml 文件,Swagger 将创建 REST 客户端。任何反馈将不胜感激!

最佳答案

是的。您可以使用 swagger-codegen-maven-plugin 生成一个 REST 客户端。但在此之前,您需要在 OpenAPI Specification 中以 YAML 或 JSON 描述 REST API。主要是因为swagger-codegen-maven-plugin只能从本规范中编写的文件生成 REST 客户端。

其他答案假定您需要手动编写规范,而我的解决方案更进一步,可以从 REST Controller 源代码自动生成规范。

最新的 OpenAPI 版本是 3.0。但根据您导入的 swagger 注释的包,您使用的是 2.0(或之前)版本。所以我的解决方案假设您使用的是 OpenAPI 2.0。

生成开放 API 规范

首先,您可以使用 swagger-maven-plugin从 RestController 源代码生成 OpenAPI 规范。基本分析了@RestController中注解的Swagger注解<locations> 中指定的类并将 OpenAPI 规范转储到 /src/main/resources/swagger.json :

<plugin>
    <groupId>com.github.kongchen</groupId>
    <artifactId>swagger-maven-plugin</artifactId>
    <version>3.1.5</version>
    <configuration>
        <apiSources>
            <apiSource>
                <springmvc>true</springmvc>
                <locations>
                    <location>com.dgs.spring.springbootswagger.controller.EmployeeController</location>
                    <location>com.dgs.spring.springbootswagger.controller.FooController</location>
                </locations>
                <schemes>
                    <scheme>http</scheme>
                </schemes>
                <host>127.0.0.1:8080</host>
                <basePath>/</basePath>
                <info>
                    <title>My API</title>
                    <version>1.1.1</version>
                </info>
                <swaggerDirectory>${basedir}/src/main/resources/</swaggerDirectory>
            </apiSource>
        </apiSources>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
</plugin>

执行以下maven命令开始生成:

mvn clean compile

生成 Rest Client

swagger.json 之后生成后,您可以将其复制并粘贴到您的客户端项目(例如/src/main/resources/swagger.json)。然后我们可以使用 swagger-codegen-maven-plugin生成 HTTP 客户端。

默认情况下,它会生成 whole maven project其中包括测试用例和其他文档资料。但我想要的只是 HttpClient 的源代码,没有其他东西。经过多次尝试和错误,我确定了以下配置:

<plugin>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-codegen-maven-plugin</artifactId>
    <version>2.4.7</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${basedir}/src/main/resources/swagger.json</inputSpec>
                <language>java</language>
                <library>resttemplate</library>
                <output>${project.basedir}/target/generated-sources/</output>

                <apiPackage>com.example.demo.restclient.api</apiPackage>
                <modelPackage>com.example.demo.restclient.model</modelPackage>
                <invokerPackage>com.example.demo.restclient</invokerPackage>

                <generateApiTests>false</generateApiTests>
                <generateModelTests>false</generateModelTests>
                <generateApiDocumentation>false</generateApiDocumentation>
                <generateModelDocumentation>false</generateModelDocumentation>
                <configOptions>
                    <dateLibrary>java8</dateLibrary>
                    <sourceFolder>restclient</sourceFolder>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>

生成的HTTP客户端基于RestTemplate,会生成到文件夹target/generated-sources/restclient .您可能必须配置 IDE 以导入生成的客户端才能使用它。 (如果是Eclipse,可以在Project Properties中配置 ➡️ Java Build Path ➡️ 添加生成的rest client的文件夹)

要开始生成客户端,只需执行 maven 命令:

mvn clean compile

使用生成的 HTTP 客户端:

ApiClient apiClient = new ApiClient();

//Override the default API base path configured in Maven
apiClient.setBasePath("http://api.example.com/api");

EmployeeManagementSystemApi api = new EmployeeManagementSystemApi(apiClient);
api.getEmployeeById(1l);

注意:

  • 如果你遇到 javax/xml/bind/annotation/XmlRootElement使用 java8+ 生成异常,可能需要引用 this .

关于java - 如何使用 Swagger codegen 开发一个简单的 REST 客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57545884/

相关文章:

java - 不同屏幕之间的文本字体大小比例

java - 在 Java 中用多个连续逗号拆分字符串

java - 如何将 Apache Commons Lang 源文件导入 Eclipse 以便编辑其代码?

java -/swagger.json 正在工作,但无法访问/api-docs?

javascript - Node.js express : loading JSON file only on server startup

java - 在 Spring Boot 中浏览 uber jar 中嵌入的文件夹的内容

spring-boot - Spring Boot 指南的问题 - 使用 LDAP 验证用户

java - 启用非安全/健康端点的 Spring Boot 2

Spring Boot - Controller 测试失败并出现 404 代码

javascript - 如何为数组 jschema 对象设置默认值?