Комментарии 6
При использовании этого решения натыкался на проблему: при наличии в контроллере более одного маппинга на один и тот же адрес, но с разными параметрами, в Сваггере в итоге все эти маппинги превращались в один эндпоинт, описание, схема и прочее которого случайно бралось от одного из маппингов, а в параметрах были абсолютно все параметры из всех маппингов по этому адресу, и с пометкой required (даже если в самих маппингах явно стоит required = false)
Судя по всему, он просто мержит все эндпоинты на основании их адреса, а не методов с маппингами. В итоге вместо нескольких нормальных маппингов получается один, в который навалено все подряд в случайном порядке, да еще и вводящие в заблуждение параметры указаны
Есть ли какой-то способ это починить?
Есть ссылка на гит* ? Без примеров кода сложно представить конструкцию.
Не обещаю что починю, но посмотрю обязательно :)
То есть, код следующего вида:
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successful operation",
content = @Content(mediaType = "application/json",
array = @ArraySchema(schema = @Schema(implementation = RegionDTO.class)))),
@ApiResponse(responseCode = "400", description = "Invalid name of region supplied", content = @Content),
@ApiResponse(responseCode = "404", description = "No regions found", content = @Content)
})
@GetMapping(params = { "name" })
public ResponseEntity<Object> getByName(
@Parameter(description = "Name of required region")
@NotBlank(message = "Region name can't be blank")
@Size(max = 255, message = "Region name can't be longer than 255 characters")
@Pattern(regexp = "[а-яА-Я() -]+",
message = "Region name must contain only Cyrillic, spaces, dashes and brackets")
@RequestParam String name) throws RecordNotFoundException {
List<RegionDTO> regionDTOs = regionDirectoryService.getByName(name);
return ResponseEntity.ok(regionDTOs);
}
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successful operation",
content = @Content(mediaType = "application/json",
array = @ArraySchema(schema = @Schema(implementation = RegionDTO.class)))),
@ApiResponse(responseCode = "400", description = "Invalid beginning of region name supplied",
content = @Content),
@ApiResponse(responseCode = "404", description = "No regions found", content = @Content)
})
@GetMapping(params = { "name-beginning" })
public ResponseEntity<Object> getByNameBeginning(
@Parameter(description = "Beginning of name of required region")
@Size(max = 255, message = "Beginning of region name can't be longer than 255 characters")
@Pattern(regexp = "[А-Я][а-я]*",
message = "Beginning of region name can't be blank, must contain only Cyrillic letters and " +
"begins with Capital one")
@RequestParam("name-beginning") String nameBeginning) throws RecordNotFoundException {
List<RegionDTO> regionDTOs = regionDirectoryService.getByNameBeginning(nameBeginning);
return ResponseEntity.ok(regionDTOs);
}
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successful operation",
content = @Content(mediaType = "application/json",
array = @ArraySchema(schema = @Schema(implementation = RegionDTO.class)))),
@ApiResponse(responseCode = "400", description = "Invalid short name of region supplied", content =
@Content),
@ApiResponse(responseCode = "404", description = "No regions found", content = @Content)
})
@GetMapping(params = { "short-name" })
public ResponseEntity<Object> getByShortName(
@Parameter(description = "Short name of required region")
@Pattern(regexp = "[А-Я]{3}",
message = "Region short name can't be blank and must be 3 Capital Cyrillic letters")
@RequestParam("short-name") String shortName) throws RecordNotFoundException {
List<RegionDTO> regionDTOs = regionDirectoryService.getByShortName(shortName);
return ResponseEntity.ok(regionDTOs);
}
Превращается в такой вот эндпоинт:
Все верно. С точки зрения REST и OpenApi - это и есть один эндпоинт, так как имеет общий uri.
Посмотрите спецификацию. Все начинается с path. Попробуйте сформулировать свое желание сначала в виде спецификации https://editor.swagger.io/ а потом сгенерировать код.
Я вижу интересный вариант по разнесению одного эндпоинта за счет применения params
, но тогда для того чтобы это работало нужно:
1. Указать параметры для спецификации как 'required = false'
2. Предусмотреть вариант когда пользователь не ввел никаких параметров "поиска". Наверняка в вашем контроллере есть что-то типа getAll() без параметров и он тоже попал в этот эндпоинт.
Я бы предложил пересмотреть подход и вместо вызова отдельных методов репозитория использовать спецификации и один энпоинт `/search`
@semo, у меня к вам есть вопрос такого характера: не сталкивались ли вы с возможной проблемой springdoc, что он не понимает контекст урла?
Например, если сервис крутится на адресе dev.host.ru/api/service/swagger-ui.html
, то при открытии он редиректит в dev.host.ru/swagger-ui.html
, документация по springdoc ничего не дала, или я не туда глядел.
«Чиним» OpenApi в springdoc-open-api