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

Integration with Swashbuckle / Swagger #259

Closed
jaredcnance opened this issue Apr 16, 2018 · 17 comments
Closed

Integration with Swashbuckle / Swagger #259

jaredcnance opened this issue Apr 16, 2018 · 17 comments

Comments

@jaredcnance
Copy link
Contributor

Several users have requested this feature but have hit errors such as:

I get System.Reflection.AmbiguousMatchException: Ambiguous match found. when I include a JSONAPIController

Does the MediaTypeHeaderValue get set automatically? I'm use Swashbuckle and all of the generated "code" is only allowing for application/json (i.e. not vnd.api+json)

@crfloyd
Copy link
Contributor

crfloyd commented Apr 18, 2018

I currently have Swashbuckle working with this library using a JsonApiController. I think the AmbiguousMatch exception arises when you override a base controller method without providing an http action attribute. I'm currently attempting to use the swaggerGen file to try to create a client library but running into issues exposing the jsonapi document model as the response model.

@wayne-o
Copy link
Contributor

wayne-o commented Apr 18, 2018 via email

@crfloyd
Copy link
Contributor

crfloyd commented Apr 27, 2018

@jaredcnance I am currently working on a way to expose an OpenAPI schema for my webservice like SwaggerGen does except that it creates the correct resource document models and all the required attribute and relationship child models that go with it. It is my hope to create an OpenAPI-complient schema doc that can be used by AutoREST to create a client to consume any api using this library. If this is something you would like integrated once I complete it, I'd be happy to issue a pull request for it.

@jaredcnance
Copy link
Contributor Author

@crfloyd that sounds fantastic. Let me know if there is anything I can do to help you.

@crfloyd
Copy link
Contributor

crfloyd commented May 7, 2018

I spent most of last week working on this and I currently have an OpenAPI 3.0 schema generating off the JsonAPIContext using Microsoft.OpenApi. It exposes paths for all the controller actions with full document responses where required. I have it in a separate project and exposed via a core Middleware. If this is something you would like to include by default in your library or via opt-in during registering the JADNC middleware, I'd like to hear your ideas on the best way to integrate with the existing library.

@jaredcnance
Copy link
Contributor Author

@crfloyd that sounds awesome. If you can share your project I’d love to play around with it some this week and get a feel for it. Depending on the surface area and dependencies, I could see an argument for either including it in the library directly or as a bolt on package.

@crfloyd
Copy link
Contributor

crfloyd commented May 7, 2018

Sounds good. I will shoot a pull request your way. I have attached an example openapi.yaml file generated by the project based on a super simple API with a student and course model. The library walks the context graph and creates resource names and comments based on what is registered there. I am still playing with the best way to include the filter,sort,page,include params for the Get requests.

openapi.zip

@crfloyd
Copy link
Contributor

crfloyd commented May 7, 2018

I had to go with OpenAPI 3.0 as 2.0 does not support DeepObject which is required for the filter[name]=foo type query params. Its a netstandard library and the only project dependencies are JsonAPIDotnetCore, Microsoft.OpenAPI and Humanizer for correct naming of things.

@lheiskan
Copy link
Contributor

@crfloyd - this sounds very useful, are you still working on this?

@wayne-o
Copy link
Contributor

wayne-o commented Jan 22, 2019

What's the situation with this? Has anyone tried more recently?

@CoolGoose
Copy link
Contributor

Bump-ing this since i would like to help @crfloyd

@jeff-becker-projekt202
Copy link

I've got a bunch of code that deals with this that my company uses internally. Once i get some down-time we'd be glad to contribute it back

@bart-degreed
Copy link
Contributor

@jeff-becker-projekt202 That would be great, looking forward to it!

@rsrobinett
Copy link

I was getting the same exception as the original post in this thread: System.Reflection.AmbiguousMatchException. In our case the issue was that swagger tries to make documentation on all public action methods. We inherit from the BaseJsonApiController with a long resource type as the generic. Then we implement the BaseJsonApiController and have public actions that take a string. The action methods in BaseJsonApiController are also public so we get an "ambiguous match" between GetAsync(long? id) and GetAsync(string id). We resolved this with an IActionModelConvention that only allows documentation for public action methods with an HttpMethodAttribute as the actions in the inheritance class are decorated with HttpMethodAttributes but those in the abstract class are not.

Here is an example of this implementation

using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Routing;

namespace JsonApiCorePrototype.Web.Documentation
{
    internal sealed class AllowDocumentationConvention : IActionModelConvention
    {
        public void Apply(ActionModel action)
        {
            //This only produces documentation for endpoints that are decorated with an HttpMethod attribute.
            //It prevents swagger from attempting to create documentation for public action methods
            //on the base controller and avoids 'Ambiguous HTTP method for action' exception.
            if (!action.Attributes.OfType<HttpMethodAttribute>().Any())
            {
                action.ApiExplorer.IsVisible = false;
            }
        }
    }
}

additionally the convention must be registered in the startup.cs configuration services.

services.AddMvcCore(options =>
            {
                options.Conventions.Add(new AllowDocumentationConvention());
            }).AddApiExplorer();

@AmrEldib
Copy link

AmrEldib commented Oct 16, 2020

Has work been done to make this work in 4.0 beta1?

I have the ToDo sample project with 4.0 beta1 working with Swashbuckle 5.6.2 (and ReDoc) in ASP.NET Core 3.1

I'm still trying to figure out how to display the correct Swagger document (some details are still wrong), but I get no build errors or run errors. JSONAPI works correctly in Postman, and Swagger UI and ReDoc loads correctly.

I don't see mention of Swagger/Swashbuckle in recent release notes, and was wondering if this was fixed or just a happy accident?

Edit: okay, I think this was a happy accident. Once I switched TodoItemsController to inherit from BaseJsonApiController instead of JsonApiController, I started getting the Ambiguous HTTP method for action error.

@bart-degreed
Copy link
Contributor

Has work been done to make this work in 4.0 beta1?

No, JADNC does not contain any logic specific for OpenAPI support and we haven't been working on that.

@bart-degreed
Copy link
Contributor

Adding OpenAPI support is now tracked at #1046.

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

No branches or pull requests

9 participants