Могу ли я заставить управление API Azure возвращать 400 вместо 404 при отсутствии требуемого поля?

#azure #azure-api-management

#azure #azure-api-management

Вопрос:

У нас есть приложение, для которого требуется наличие некоторых полей. Если эти поля отсутствуют, мы вернем ответ 400, объясняющий, чего не хватает в соответствующем сообщении об ошибке. Кажется, добавление APIM в микс сильно усложняет его. Поскольку APIM знают, что поле является обязательным, похоже, что оно сократит curcuit и вернет 404 с общим сообщением вместо нашего самоочевидного сообщения о том, что не так.

Это способ отключить эту функциональность для APIM?

Комментарии:

1. Под полем вы подразумеваете параметры запроса?

2. ДА. У нас есть несколько обязательных полей. Я понимаю, что APIM делает что-то из лучших побуждений, но я бы предпочел контролировать сообщение об ошибке здесь.

3. Я не думаю, что он ответит 404, если в параметрах запроса отсутствуют поля. Ошибка 404 может быть просто ответом при запросе неправильного URL. Не могли бы вы предоставить образец вашего внутреннего URL-адреса, а также образец вашего APIM api?

4. Но в том-то и дело. Поскольку у нас есть параметры запроса по мере необходимости, apim замкнет запрос на 404, если требуемый параметр отсутствует, и вернет 404 вместо того, чтобы пропустить запрос в приложение. Так что, возможно, это неправильное описание.

5. Я сам столкнулся с этой проблемой. Я обнаружил, что APIM импортирует мои требуемые параметры запроса в качестве параметров шаблона, что приводит к сбою сопоставления URL-адресов, когда запрос не предоставлен. Однако можно редактировать конечные точки после их импорта из спецификации OpenAPI. Я смог удалить параметр шаблона и добавить требуемый параметр запроса, который работает должным образом. Смотрите Мой вопрос по адресу docs.microsoft.com/en-us/answers/questions/829259 /…

Ответ №1:

Я получаю ту же проблему, и в конечном итоге меняю свой подход. Что я сделал, так это настроил его на стороне приложения и использовал FluentValidation, чтобы сделать параметры строки запроса обязательными. Итак, моя модель теперь выглядит примерно так:

 using FluentValidation;

public class UrlQueryParameters
{
    public string PropertyA { get; set; }
    public string PropertyB { get; set; }
}

public class UrlQueryParametersValidator : AbstractValidator<UrlQueryParameters>
{
    public UrlQueryParametersValidator()
    {
        RuleFor(o => o.PropertyA)
            .NotEmpty()
            .WithMessage("The 'PropertyA' parameter was missing or a value was not provided.");

        RuleFor(o => o.PropertyB)
            .NotEmpty()
            .WithMessage("The 'PropertyB' parameter was missing or a value was not provided.");
    }
}
 

Предыдущий код определяет несколько правил проверки с пользовательскими сообщениями PropertyA и PropertyB свойствами.

Теперь включите FluentValidation в качестве механизма проверки по умолчанию для нашего приложения, добавив следующий код в ConfigureServices метод Startup.cs file:

 public void ConfigureServices(IServiceCollection services) {
    // Rest of the code omitted for brevity
    
    services
      .AddControllers()
      .AddFluentValidation(fv => 
      { 
          fv.DisableDataAnnotationsValidation = true;
          
          // The following line registers ALL public validators in the assembly containing UrlQueryParametersValidator
          // There is no need to register additional validators from this assembly.
          fv.RegisterValidatorsFromAssemblyContaining<UrlQueryParametersValidator>(lifetime: ServiceLifetime.Singleton);
      });
}
 

На этом этапе конечные точки вашего API должны проверять требуемые параметры из запроса, и APIM не должен замыкать запрос, вызывая 404 Not Found его при попытке доступа /api/foo/{id} .

Причина, по которой это работает, заключается в том, что Swashbuckle автоматически не импортирует правила проверки из FluentValidation. Это означает, что свойства PropertyA и PropertyB не будут помечены как требуемые при их просмотре в пользовательском интерфейсе Swagger. Это недостаток этого подхода, поскольку требуемые параметры строки запроса из пользовательского интерфейса Swagger не будут помечены как требуемые, что может сбить с толку потребителей. Но для меня важнее вернуть правильный код состояния с содержательным сообщением потребителям, и именно поэтому я пока буду придерживаться этого обходного пути. Вы могли бы попробовать использовать параметр MicroElements.Swashbuckle.FluentValidation to altleastустановить / пометить параметры, как требуется в схеме пользовательского интерфейса Swagger. Но это только об этом.

Я писал об этом в блоге здесь: грязный взлом при создании требуемых параметров строки запроса для работы в Azure APIM

Ответ №2:

В разделе надстройки политики API / продукта / глобального уровня -ошибка, используйте выбрать политику, чтобы проверить, была ли найдена операция или нет:

 <choose>
  <when condition="@(context.LastError.Source == "configuration" amp;amp; context.LastError.Reason == "OperationNotFound")">
    <return-response>
      <set-status code="400" reason="Bad Request" />
    </return-response>
  </when>
</choose>
 

Комментарии:

1. Спасибо, но, возможно, мне следует уточнить, что я имею в виду. Похоже, что APIM «перехватывает» запрос и возвращает 404, даже не вызывая серверную часть, поскольку она не может соответствовать операции. Это было не то поведение, которого я ожидал.

2. Затем вы должны пометить эти параметры запроса как необязательные. Тогда APIM будет сопоставлять операции с параметрами запроса и без них.

3. Я не думаю, что это ответ. Я хочу, чтобы спецификация генерировала по мере необходимости, чтобы вы могли прочитать спецификацию open api и посмотреть, что вы должны предоставить. Я также хочу возвращать исправные сообщения об ошибках, если кто-то не соблюдает спецификацию, а это невозможно при поведении apim.