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

Swagger/OpenAPI support #183

Open
nickrandolph opened this issue Aug 9, 2021 · 4 comments
Open

Swagger/OpenAPI support #183

nickrandolph opened this issue Aug 9, 2021 · 4 comments
Labels
question Further information is requested

Comments

@nickrandolph
Copy link

Has anyone used Swagger (eg Swashbuckle) to document an API that exposes a CloudEvent (eg adding Swagger to this sample)?

I'm seeing a bunch of clr types being added to the swagger.json (Type, Assembly etc). This seems to be caused by the CloudEventAttributeType exposing the property ClrType which returns a Type.

I was wondering whether this is a known issue, and whether there's an existing workaround?

I was considering customizing the swagger by providing an override for Type eg https://github.com/cloudevents/sdk-csharp/tree/master/samples/CloudNative.CloudEvents.AspNetCoreSample

@jskeet
Copy link
Contributor

jskeet commented Aug 9, 2021

I don't know anything about integrating Swagger and ASP.NET Core, but if Swagger is expecting to serialize and deserialize the events itself, that needs to be changed - event formatters must be involved for that.
It's entirely possible that we should have a separate project for ASP.NET Core + Swashbuckle integration, but I don't know enough about it to do that myself.

@jskeet jskeet added the question Further information is requested label Aug 9, 2021
@nickrandolph
Copy link
Author

nickrandolph commented Aug 9, 2021

I've spent a bit of time investigating this today. Firstly, the generating of Swagger/OpenApi doesn't affect the operating of the service. I've been able to successfully send cloudevents to my service and process them correctly.

However, I was hoping that I'd be able to use openapi to describe the service that I expose entirely. I see that there's a Json-Schema spec (ie https://github.com/cloudevents/spec/blob/v1.0.1/spec.json) which I've tried to use as a OpenApiSchema for the CloudEvent type eg

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Defects", Version = "v1" });
    c.CustomSchemaIds(schemaIdStrategy);
    c.MapType<CloudEvent>(() =>
        {
            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Defects.cloudevents.spec.v1.0.1.json"))
            {
                var reader = new OpenApiStreamReader();
                var diagnostic = new OpenApiDiagnostic();
                return reader.ReadFragment<OpenApiSchema>(stream, OpenApiSpecVersion.OpenApi3_0, out diagnostic);
            }
        }
    );
});

Unfortunately, for some reason when I try to incorporate this as part of the openapi for my service, I just get a series of "object" properties, rather than the useful info that's in the spec.

"application/json": {
              "schema": {
                "required": [
                  "id",
                  "source",
                  "specversion",
                  "type"
                ],
                "type": "object",
                "description": "CloudEvents Specification JSON Schema - exported"
              }
            },

@jskeet
Copy link
Contributor

jskeet commented Aug 9, 2021

Unfortunately this is beyond my knowledge of Swagger. I would say that even if this had worked, it would still be non-ideal, in terms of not talking about the CloudEvent-specific schema. Of course, if your service is expecting to be able to handle all CloudEvents, that's fine. But otherwise I'd expect the data to be described in terms of your actual expected event schema.

@captainsafia
Copy link
Contributor

Chiming in on this old issue as the OpenAPI/Swagger SME for ASP.NET Core 😄

OpenAPI generation tools like Swashbuckle (used here) will try to generate an OpenAPI/JSON schema for a given .NET type by walking the properties on the type and extrapolating an appropriate schema definition for them. This makes sense for certain properties on the CloudEvent like subject and source and specVersion.

However, the concept of extensionAttributes in a CloudEvent doesn't map to a discrete property in this case. The right way to represent the existence of extension attributes is to set the additionalProperties: true property in the generated JSON schema to indicate that in addition to the required set of properties it supports an arbitrary set of extension attributes.

For this particular case, I'd recommend using a SchemaFilter to mutate the schema that is generated by Swashbuckle to omit the extensionAttributes property and set additionalProperties: true.

All this aside, there's a bit of an incongruence between the types of data that OpenAPI is meant to represent and the ways that OpenAPI represents data. You lose a lot of color in the default generation approach with regards to the differences in structured vs. binary mode messages, the formats of the body, etc.

I dunno if there's anything we'd want to do built-in within the CloudEvents SDK to support this. I think using the customization APIs used in existing OpenAPI generators to modify the schema according to what is known about the expected structure/format.

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

No branches or pull requests

3 participants