Você já se ajustou durante o hotfix ao mestre? Não ?! Mas eu consegui!
Esta história é sobre como eu esqueci de atualizar a documentação. Como resultado, escrevi um plugin para o Swagger (pela segunda vez). E como eu me empolguei com isso, para que eu esquecesse minha licença médica e fui em paz!
E um pouco mais sobre o opcional
não do Java 8.
Usamos o
Swagger para criar documentação interativa.
Portanto, quando você cria um método na API, então:
0. Adicione as anotações necessárias, como @RequestMapping e assim por diante.
1. Adicione @ErrorCodes (nossa própria anotação) e liste os códigos de erro de sequência que esse método pode retornar na resposta.
2. Adicione @ApiOperation e duplique informações sobre esses erros no campo de anotações.
3. Adicione o restante das anotações ...
Parecia algo assim (removido desnecessário e simplificado):
@ApiOperation( value = "Some description.", notes = "List of possible error codes:" + "<ul>" + " <li>sms.verification.code.fail</li>" + "</ul>") @PostMapping("/security/confirmation/check") @ErrorCodes(values = {"sms.verification.code.fail"}) public ResponseDto check(@ApiParam @RequestBody @Valid RequestDto request) {... }
O ponto 2 foi a fonte da minha falha quando adicionei @ErrorCodes, mas esqueci de listar os códigos de erro em @ApiOperation. Satisfeito comigo mesmo, mas com um leve senso de ansiedade, dei minha solicitação de solicitação de revisão de código. E aqui eles me informaram que eu esqueci as anotações! Eles também explicaram que o Swagger não coleta informações de @ErrorCodes e é por isso que você precisa registrá-las manualmente. Naquela noite, tudo terminou feliz. Corrigiu seu defeito e saiu de licença médica.
Talvez fosse normal seguir em frente. Coloque uma marca de verificação na prateleira para os outros da mesma forma que eles dizem, Max, tenha cuidado, preste atenção nisso ...
Mas não tive sucesso. A noite toda e a manhã seguinte foram dedicadas a ensinar o Swagger a ler nossa anotação e a adicionar independentemente esses mesmos códigos nas anotações.
Etapa 1. Alguém estava aqui ...
A partir de uma pesquisa superficial, consegui descobrir que alguém já havia
tentado fazer amizade com o Swagger com sua anotação. Havia também um link para a documentação do SpringFox que dizia que você pode escrever um plugin!
A felicidade feliz me cobriu tanto que até me esqueci do frio e da baixa por doença! No meu futuro artigo,
“Como não deixar a empresa três vezes”, compartilho três histórias de salvar pessoas que estão se afogando. Uma delas é sobre como eu consegui escrever um plugin para o Chrome + Firefox, que acelerou o trabalho com Jenkins várias vezes. Eu era tão divertido escrever isso! Afinal, este é um microprojeto! Minha inicialização muito, muito simples, mas com pessoas reais que a usam. Então eu saí da rotina novamente e encontrei inspiração. O esgotamento se foi. Mas é melhor falar sobre isso em um artigo futuro. Enquanto isso, volte ao plugin do Swagger.
Ação 2. Funciona!
Escrever algo que funcionou acabou sendo fácil. Tomei um exemplo de um plug-in da documentação oficial do SpringFox, removi tudo desnecessário e adicionei o correto.
Plugin. Versão 1 @Component @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1) public class SwaggerErrorCodesConfiguration implements OperationBuilderPlugin { @Override public void apply(OperationContext context) { Method operationMethod = context.getHandlerMethod().getMethod();
Comecei a testar com um método que não especifica um valor para anotações em @ApiOperation.
@ApiOperation(value = "Some description.") @PostMapping("/security/confirmation/check") @ErrorCodes(values = {"sms.verification.code.fail"}) public ResponseDto check(@ApiParam @RequestBody @Valid RequestDto request) { ... }
Lançamento e ... O resultado! Viva, funciona! O código da string
sms.verification.code.fail apareceu nas notas!

Etapa 3. Funciona, mas não funciona.
Em seguida, adicionei algumas palavras às notas e recebi este código:
@ApiOperation(value = "Some description.", notes = "Some initial note.") @PostMapping("/security/confirmation/check") @ErrorCodes(values = {"sms.verification.code.fail"}) public ResponseDto check(@ApiParam @RequestBody @Valid RequestDto request) { ... }
Lançado novamente. O resultado foi ... inesperado. O plugin SpringFox sobrescreve o valor das notas ao gerar documentação (O_o)!
Observo como
context.operationBuilder (). Notes (String) funciona e vejo o seguinte:
public OperationBuilder notes(String notes) { this.notes = (String)BuilderDefaults.defaultIfAbsent(notes, this.notes); return this; }
Um ... Ok, então vamos pegar o valor atual das notas e adicionar códigos de erro. Resta obter a anotação @ApiOperation, pegar o valor desejado e adicionar ao que estou me formando.
Portanto, a versão final (
disponível em gist.github.com )
Plugin. Versão 2 @Component @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1) public class SwaggerErrorCodesConfiguration implements OperationBuilderPlugin { @Override public void apply(OperationContext context) { Method operationMethod = context.getHandlerMethod().getMethod();
Agora acabou como deveria!

Etapa 4. E o Opcional não do Java 8?
No começo do trabalho no plug-in, eu não conseguia entender o que havia de errado com o opcional, que é retornado ao procurar anotações. Esta classe não possui os métodos padrão usados para trabalhar com
java.util.Optional . Por exemplo, não há método
ifPresent , mas existe um método
ouNull .
Descobriu-se que o SpringFox usa o
opcional da
goiaba .
TL; DR
Eu escrevi um plug-in para o SpringFox, que é um componente do Spring e é chamado no estágio de geração da documentação para ler valores da nossa anotação @ErrorCodes.
Código do plugin @Component @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1) public class SwaggerErrorCodesConfiguration implements OperationBuilderPlugin { @Override public void apply(OperationContext context) { Method operationMethod = context.getHandlerMethod().getMethod();