Сопоставление приводов Spring Boot: добавьте описание конечных точек | Весенняя загрузка 3.3.0

Я использую Spring Doc Open API в своем проекте весенней загрузки. В моем контроллере отдыха у меня есть две конечные точки, которые идентичны и отличаются только параметрами и содержимым тела запроса. Пример:

@PostMapping(value = "/v1/types", params = "type=typeA) 
...
@PostMapping(value = "/v1/types", params = "type=typeB)

Согласно спецификации OpenAPI, конечная точка должна быть уникальной, а параметры не считаются частью пути. Итак, пользовательский интерфейс Swagger показывает только одну конечную точку, я думаю, первую в алфавитном порядке.

В моем случае моя команда внешнего интерфейса должна знать, какие конечные точки использовать в моем API. Итак, я нахожу альтернативу активатору конечной точки /mappings, которая показывает каждую конечную точку в моем проекте именно то, что мне нужно.

Моя проблема в том, что мне нужно добавить описание для каждой конечной точки, чтобы описать, какие объекты требуются и что именно делает конечная точка.

Есть ли способ добавить какое-то описание для конечных точек, перечисленных в /actuator/mappings?

К вашему сведению: Spring Boot 3.3.0

Я много пробовал с API Swagger, например, добавляя несколько данных к конечным точкам, например, с помощью аннотаций @Operation, @APIResponses или @Parameter, но это не помогает отображать одну и ту же конечную точку с разными параметрами.

Я посмотрел официальную документацию по приводу Spring Boot, но информации о ней нет.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
125
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать пружинный привод, как показано ниже,

Добавьте зависимость в ваш pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Создайте пользовательскую конечную точку

@Component
@Endpoint(id = "custommappings")
public class CustomMappingsEndpoint {

    private final ApplicationContext applicationContext;

    @Autowired
    public CustomMappingsEndpoint(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @ReadOperation
    public Map<String, Object> customMappings() {
        Map<String, Object> mappings = new HashMap<>();
        Map<String, RequestMappingHandlerMapping> allRequestMappings = applicationContext
                .getBeansOfType(RequestMappingHandlerMapping.class);
        for (RequestMappingHandlerMapping handlerMapping : allRequestMappings.values()) {
            Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();

            for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
                RequestMappingInfo requestMappingInfo = entry.getKey();
                HandlerMethod handlerMethod = entry.getValue();

                // Extract path from PathPatternsRequestCondition
                PathPatternsRequestCondition pathPatternsCondition = requestMappingInfo.getPathPatternsCondition();
                Set<String> patterns = pathPatternsCondition != null ? pathPatternsCondition.getPatternValues() : null;

                if (patterns != null && !patterns.isEmpty()) {
                    if (isExcludedPath(patterns.iterator().next())) {
                        continue; // Skip this path
                    }
                }

                Map<String, Object> endpointInfo = new HashMap<>();
                endpointInfo.put("path", patterns.iterator().next());
                endpointInfo.put("methods",
                        requestMappingInfo.getMethodsCondition() != null
                                ? requestMappingInfo.getMethodsCondition().getMethods()
                                : "unknown");
                endpointInfo.put("params",
                        requestMappingInfo.getParamsCondition() != null
                                ? requestMappingInfo.getParamsCondition().getExpressions()
                                : "unknown");
                endpointInfo.put("description", handlerMethod.getMethod().getName());

                mappings.put(handlerMethod.getMethod().getName(), endpointInfo);
            }
        }

        return mappings;
    }

    private boolean isExcludedPath(String path) {
        // Define paths to exclude
        return path.startsWith("/v3/api-docs") || path.startsWith("/error") || path.startsWith("/swagger-ui.html")
                || path.startsWith("/v3/api-docs.yaml");
        // Add more paths as needed
    }

Предоставьте пользовательскую конечную точку в вашем application.properties.

management.endpoints.web.exposure.include=custommappings

Используйте приведенный ниже URL-адрес, чтобы получить информацию о конечной точке,

http://server:port/context-path/actuator/custommappings

Выход:

{"method1":{"path":"/v1/types","methods":["POST"],"description":"method1","params":[{"name":"type","value":"typeA","negated":false}]},"method2":{"path":"/v1/types","methods":["POST"],"description":"method2","params":[{"name":"type","value":"typeB","negated":false}]},"method3":{"path":"/v1/getTypes","methods":["GET"],"description":"method3","params":[]}}

В этом случае мне пришлось создавать документацию вручную, например внутренний словарь. Конечная точка по умолчанию для всех конечных точек в проекте — /actuator/mappings. Это означает, что пользовательские сопоставления конечной точки/актуатора/пользовательских будут отображать только описанные конечные точки в customMappings(), не так ли? Есть ли какой-либо другой способ показать остальные конечные точки API общедоступному (интерфейсу), кроме пользовательского интерфейса Swagger, который мог бы поддерживать отображение одних и тех же конечных точек с разными параметрами (Requestparam)?

Nick M. 18.06.2024 12:59

обновлен код для создания документации для всех конечных точек, которая отображается в /actuator/custommappings

Abhishek Kotalwar 19.06.2024 10:15

Другие вопросы по теме