# API response consistency

The `ApiResponseFilter` is an action filter attribute that provides consistent structure to API responses. It wraps the API response body within an `ApiResponse` class.

```csharp
/// <summary>
/// Api response
/// </summary>
public class ApiResponse
{
    /// <summary>
    /// Error messages
    /// </summary>
    public string[]? Errors { get; init; }

    /// <summary>
    /// Success flag
    /// </summary>
    public bool IsSuccess { get; init; }

    /// <summary>
    /// Response body
    /// </summary>
    public object? Data { get; init; }

    /// <summary>
    /// Status code
    /// </summary>
    public HttpStatusCode StatusCode { get; init; }
}
```

#### Model Validation

If the model state is invalid, the filter captures the errors and returns a structured error response with an HTTP status code of `400 Bad Request`.

#### Installation

```bash
dotnet add package Eiffel.CrossCutting.ApiResponseConsistency
```

You should install **Eiffel.CrossCutting.ApiResponseConsistency** NuGet package into your application.&#x20;

#### Usage

To apply this filter, decorate your controllers or actions with `[ApiResponseFilter]`.

{% hint style="info" %}
For better experience decorate your metho&#x64;**`ProducesDefaultResponseType`**&#x61;nd **`ProducesResponseType`**&#x62;y using **ApiResponse** and **ApiResponse\<T>** classes.
{% endhint %}

```csharp
[ApiResponseFilter]
public class BookingController : ControllerBase
{
    [HttpPost]
    [ProducesDefaultResponseType(typeof(ApiResponse))]
    [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ApiResponse<CreateBookingResponse>))]
    public async Task<CreateBookingResponse> PostAsync([FromBody] CreateBookingRequest request)
    {
        // Your implementation details..
    }
}
```

To appy this filter to all controllers in your application, add to Mvc filters.

```csharp
// Program.cs (.NET5 and above)
public static async Task Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);
    
    // Applies api response filter for all controllers
    builder.Services.AddControllers(options =>
    {
        options.Filters.Add<ApiResponseFilter>();
    });
     
    var app = builder.Build();
    app.Run();
}
```

**Disabling consistency for specific actions/controllers**

If you don't want a particular action or controller to be wrapped with this consistency logic, decorate it with the `DisableApiResponseConsistency` attribute.

```csharp
[DisableApiResponseConsistency]
public class FileController : ControllerBase
{
    [HttpPost]
    public async Task PostAsync(IFormFile file)
    {
        // Your implementation details..
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.eiffel.dev/features/cross-cutting-concerns/api-response-consistency.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
