Documentar

Olá a todos! Neste artigo, gostaria de considerar as ferramentas de documentação em abordagens fundamentalmente diferentes para o desenvolvimento da API REST, a saber, para as ferramentas CodeFirst - SpringRestDocs (bem como seu complemento SpringAutoRestDocs) e para ApiFirst - ferramentas do ecossistema Swagger (Open-Api).





Aviso: Não entrarei em detalhes do holivar sobre o que é melhor que CodeFirst ou ApiFirst, mas tentarei demonstrar a possível prática de documentação em ambas as versões.





CodeFirst plus SpringAutoRestDocs

SpringRestDocs , (, ..) . , , - , .. SpringAutoRestDocs, JSR Spring , Javadoc, .





SpringAutoRestDocs

SpringAutoRestDocs SpringRestDocs, . - .





:





  • , Jackson, Javadocs





  • JSR-303









.





Swagger PetStore ( , ) (addPet



, deletePet



, getPetById



). getPetById







:





@RestController
@RequiredArgsConstructor
public class PetController implements PetApi {

    private final PetRepository petRepository;
    
    @Override
    public ResponseEntity<Pet> getPetById(Long petId) {
        return new ResponseEntity<>(petRepository.getPetById(petId), HttpStatus.OK);
    }
  //   
}
      
      



.





:





, . , MockMvc



( ):





@Before
void setUp() throws Exception {
  this.mockMvc = MockMvcBuilders
    .webAppContextSetup(context)
    .alwaysDo(prepareJackson(objectMapper, new TypeMapping()))
    .alwaysDo(commonDocumentation())
    .apply(documentationConfiguration(restDocumentation)
           .uris().withScheme("http").withHost("localhost").withPort(8080)
           .and()
           .snippets().withTemplateFormat(TemplateFormats.asciidoctor())
           .withDefaults(curlRequest(), httpRequest(), httpResponse(),
                         requestFields(), responseFields(), pathParameters(),
                         requestParameters(), description(), methodAndPath(),
                         section(), links(), embedded(), authorization(DEFAULT_AUTHORIZATION),
                         modelAttribute(requestMappingHandlerAdapter.getArgumentResolvers())))
    .build()
  }

protected RestDocumentationResultHandler commonDocumentation(Snippet... snippets) {
  return document("rest-auto-documentation/{class-name}/{method-name}", commonResponsePreprocessor(), snippets)
  }

protected OperationResponsePreprocessor commonResponsePreprocessor() {
  return preprocessResponse(replaceBinaryContent(), limitJsonArrayLength(objectMapper), prettyPrint())
  }
      
      



MockMVC

WebApplicationContext



@SpringBootTest







prepareJackson(objectMapper, new TypeMapping())



ResultHandler



, pojo





withDefaults(curlRequest(), httpRequest(), ..)



,





commonDocumentation()



, build , .





:





.





@Test
void getPetTest() {
//given
def petId = 1L
//when
def resultActions = mockMvc
	.perform(RestDocumentationRequestBuilders
		.get("/pet/{petId}", petId)
		.header("Accept", "application/json"))
//then
resultActions
	.andExpect(status().isOk())
	.andExpect(content().string(objectMapper.writeValueAsString(buildReturnPet())))
}
      
      



MockMvc



, .





:





"" auto-section.adoc



( , MockMVC



) index.adoc



API. :





: , html .





SprinAutoRestDocs , . , .





SpringAutoRestDocs SpringRestDocs.





  • - org/springframework/restdocs/templates/asciidoctor default-



    .





  • - org/springframework/restdocs/constraints DefaultConstraintDescriptions.properties



    .





:





ApiFirst Swagger

(1, 2) swagger - open-source , OpenApi Specification , REST api.





Swagger

Swagger - OpenApi Specification Swagger Tools.





  • OpenApi Specification - REST API. YAML JSON. , .





  • Swagger Tools - , - REST api. : Swagger Editor( , ), Swagger UI( API), Swagger Codegen( - , )





- : (swagger-library), swagger-ui(swagger-webjar-ui-starter), (spring-auto-rest-docs).





Swagger Swagger PetStore SpringAutoRestDocs .





build.gradle :





server stub Swagger OpenApi Generator.





OpenApi Generator

gradle gradle plugin OpenApi Generator.





- , . .





:





openApiGenerate {
    generatorName = 'spring'
    inputSpec = specFile
    outputDir = "${project.projectDir}/"
    id = "${artifactId}"
    groupId = projectPackage
    ignoreFileOverride = ignoreFile
    apiPackage = "${projectPackage}.rest.api"
    invokerPackage = "${projectPackage}.rest.invoker"
    modelPackage = "${projectPackage}.rest.model"
    configOptions = [
            dateLibrary            : 'java8',
            hideGenerationTimestamp: 'true',
            interfaceOnly          : 'true',
            delegatePattern        : 'false',
            configPackage          : "${projectPackage}.configuration"
    ]
}
      
      



openApiGenerate
  • generatorName -





  • Spring ( spring)





  • dateLibrary - (joda, JSR-310 ..)





  • ,





:





task codegen(dependsOn: ['openApiGenerate', 'copySpecs'])

compileJava.dependsOn(codegen)
compileJava.mustRunAfter(codegen)
      
      



, UI :





task copySpecs(type: Copy) {
    from("${project.projectDir}/specs")
    into("${project.projectDir}/src/main/resources/META-INF/specs")
}
      
      



Asciidoc Html2.





Swagger-ui :





webjar swagger-ui .





Rest-docs API:





UI :





@RestController
@RestController
@RequiredArgsConstructor
public class PetController implements PetApi {

    private final PetRepository petRepository;
    
    @Override
    public ResponseEntity<Pet> getPetById(Long petId) {
        return new ResponseEntity<>(petRepository.getPetById(petId), HttpStatus.OK);
    }
  //   
}
      
      



swagger:
  ui:
    indexHandler:
      enabled: true
      resourceHandler: "/api/**"
    apis:
      - url: http://localhost:8080/specs/some_swagger.yaml
        name: My api
      
      



:





Server stub - API.





Swagger UI - API UI:





Asciidoc Html2 swagger :





:

SpringAutoRestDocs:





  • ( index.html ), .





  • , "" .





  • A capacidade de personalizar trechos e restrições.





O que Swagger oferece:





  • Um único artefato em todos os estágios de desenvolvimento.





  • A documentação e o modelo de dados estão sempre em sincronia com o código, pois o código é gerado com base em um contrato.





  • A capacidade de usar uma IU que contém todas as mesmas informações do contrato com a capacidade de encaminhar solicitações.





Qualquer que seja o caminho de desenvolvimento que você escolher, as ferramentas acima quase sempre permitirão que você mantenha a documentação atualizada intimamente relacionada ao código de produção.








All Articles