Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate ExamplesOperationFilter #108

Closed
mattfrear opened this issue Aug 16, 2019 · 11 comments
Closed

Deprecate ExamplesOperationFilter #108

mattfrear opened this issue Aug 16, 2019 · 11 comments

Comments

@mattfrear
Copy link
Owner

mattfrear commented Aug 16, 2019

Since May 2018, Swashbuckle.AspNetCore supports adding examples via XML comments:

public class Product
{
    /// <summary>
    /// The name of the product
    /// </summary>
    /// <example>Men's basketball shoes</example>
    public string Name { get; set; }

Unfortunately it doesn't work correctly at the moment - ints are rendered as strings. The bugfix has been implemented but not yet released. domaindrivendev/Swashbuckle.AspNetCore#959

Once that fix gets released, I think I can begin to deprecate my examples filter... which is pretty much this repo's raison d'être.

@mattfrear mattfrear changed the title Deprecate Examples filter Deprecate ExamplesOperationFilter Aug 16, 2019
@tomkludy
Copy link

There are several problems with the XML comment based examples, so I hope you don't actually proceed with deprecating this until they are resolved...

Among the problems:

  • Does not work in combination with Redoc's option to only show Required properties in samples. So there's no way to provide examples for models where all properties are optional (for example, PATCH style operations), or include optional properties in the example. The ExamplesOperationFilter works fine in this case, allowing me to add a few targeted examples and leave the other 90% of my API just showing defaults for required values only.

  • Does not support examples in context when a model is referenced by multiple other models. An example of where this is necessary:

public class Reference
{
    /// <summary>
    /// Id of the referenced item.
    /// </summary>
    public string Id { get; set; }

    /// <summary>
    /// Name of the referenced item.
    /// </summary>
    public string Name { get; set; }
}

public class Widget
{
    /// <summary>
    /// Container this is inside of.
    /// </summary>
    public Reference WidgetContainer { get; set; }

    /// <summary>
    /// Dongles compatible with this Widget.
    /// </summary>
    public Reference[] CompatibleDongles { get; set; }
}

In this model, I don't want the Reference example to be the same everywhere, I want it to be different in the WidgetContainer property example vs. the CompatibleDongles property example.

  • The above also illustrates another problem, that the example XML comment can't handle lists properly.

  • Finally, although neither the example XML comment nor the ExamplesOperationFilter supports multiple examples for the same model today (Add support for multiple examples #109 )... this seems like it will be much more manageable using an ExamplesOperationFilter rather than trying to match up the example XML comment on every property.

Maybe I'm missing how to accomplish these things with the XML comments... if so, I would be happy to be mistaken! I'm all for having fewer dependencies as long as I can achieve what I need...

@CumpsD
Copy link
Contributor

CumpsD commented Oct 22, 2019

@mattfrear does this also mean you are considering dropping IExamplesProvider?

@mattfrear
Copy link
Owner Author

@CumpsD I am, yes. I mostly have simple use cases for my examples which could be met by XML comments. Although @tomkludy above has stated a pretty strong case for leaving IExamplesProvider.

@CumpsD
Copy link
Contributor

CumpsD commented Oct 23, 2019

We use it to generate examples which contain values unknown at design time, so the xml comments wouldn't work either.

Our examples use dependency injection with the configuration to get values, and we also generate examples in code.

@mattfrear
Copy link
Owner Author

Thanks @CumpsD those are valid use cases too. I'll leave it for now.

@sabbadino
Copy link

sabbadino commented Dec 22, 2019

yes, please leave support for IExamplesProvider
as for @CumpsD , I need to generate examples at run time (reading some data from DB).. In my case XML comments would be an option at all.

@P47K0
Copy link

P47K0 commented Mar 11, 2021

I use a wrapper for the response so the response always has the same structure (for error and normal responses):

public class ResponseMessage<T> where T : class
{        
	public ResponseMessage(T data)
	{
		Data = data;
	}
	
	public ResponseMessage(IList<ErrorDto> modelValidationErrors)
	{
		Errors = modelValidationErrors;
		Success = false;
	}
	
	public T Data { get; set; } = default;
	
	public bool Success { get; set; } = true;
   
	public IList<ErrorDto> Errors { get; set; } = null;
}

I needed to supply different examples for different status codes, one for status code 200 and two for status code 400.
I couldn't see how to do this via the xml comments so I used your SwaggerResponseExample for that.
This works great, thanks!

Don't deprecate it please!

@lonix1
Copy link
Contributor

lonix1 commented Jul 11, 2021

My use case is I generate examples using random data, dynamically at runtime using https://github.com/bchavez/Bogus.

So on each page load I get new random data!

public class UserExample : IExamplesProvider<User> {

  public User GetExamples() =>
    new Faker<User>()
    .StrictMode(true)
    .RuleFor(x => x.Email,    x => x.Person.Email)
    .RuleFor(x => x.Password, x => x.Internet.Password())
    .RuleFor(x => x.Name,     x => x.Person.FullName)
    .Generate();

}

Same thing for response examples.

Please don't deprecate! 🙏

@PeterMontgomery777
Copy link

...like @sabbadino, I'm retrieving the example data from the DB that the API instance is pointing to, where I configure examples via a APISwaggerExample table:

public IEnumerable<SwaggerExample<SupporterDTO>> GetExamples()
{
  using var scope = _scopeFactory.CreateScope();
  using var context = scope.ServiceProvider.GetRequiredService<ImportConfigDBContext>();

  var examples = context.APISwaggerExamples.Where( e => e.DTOName == "SupporterDTO" ).Select(e => new SwaggerExample<SupporterDTO>
  {
      Name = e.Name,
      Value = new SupporterDTO { Format = e.Format, Keyword = e.Keyword, Street = e.Street, Codeword = e.Codeword /*...etc. */ }
  }).ToList();

  return examples;
}

So another "please don't deprecate" from me 🙏

...unless there is a better way of doing it, of course!

@a-patel
Copy link

a-patel commented Feb 8, 2022

"Swashbuckle.AspNetCore.Filters" seems to be very scalable/extensible as compared to native XML comments. Dynamic examples can be generated very easily with it. I think this should be left as it is, till such things are not available natively.

@mattfrear
Copy link
Owner Author

Don't worry folks, I'm not gonna deprecate it any time soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants