OperationFilter - Getting Request/Response DTO types

Back in SS Swagger 1.2 days, I could do something like this:

var requestType = Utilities.GetTypesWhere(m => m.Namespace?.StartsWith("XXXXX") == true && m.Name.EqualsIgnoreCase(operation.OperationId)).FirstOrDefault();

Basically, I could take the operation name and find the starting type. Not super efficient, but it worked. Now with the new naming conventions, I can’t do that.

I add my own custom annotations that I then use to alter the default operation descriptions and summary info.

Any way we can get the OperationFilter or ApiDeclarationFilter
to include the actual Types for the request/response DTOs? Or at least expose a bunch of those private static methods that are in OpenApiService so we can take our known types and recreate the exact OperationId so we can “retrace” and find the original types?

Not sure if this is the best solution, but just in case someone else needs to do this, here’s my hack workaround.

ApiDeclarationFilter:

swagger.ApiDeclarationFilter = declaration =>
{
foreach(var path in declaration.Paths)
{
string ct = null;
OpenApiOperation operation = null;
Type requestType = null;

                if(path.Value.Get != null)
                {
                    operation = path.Value.Get;

                    requestType = RestHandler.FindMatchingRestPath("GET", path.Key, out ct)?.RequestType;
                }
                else if(path.Value.Post != null)
                {
                    operation = path.Value.Post;

                    requestType = RestHandler.FindMatchingRestPath("POST", path.Key, out ct)?.RequestType;
                }
                else if(path.Value.Put != null)
                {
                    operation = path.Value.Put;

                    requestType = RestHandler.FindMatchingRestPath("PUT", path.Key, out ct)?.RequestType;
                }
                else if(path.Value.Patch != null)
                {
                    operation = path.Value.Patch;

                    requestType = RestHandler.FindMatchingRestPath("PATCH", path.Key, out ct)?.RequestType;
                }
                else if(path.Value.Delete != null)
                {
                    operation = path.Value.Delete;

                    requestType = RestHandler.FindMatchingRestPath("DELETE", path.Key, out ct)?.RequestType;
                }

                if(operation != null && requestType != null)
                {
                    ....

OpenAPI requires that all OperationId must be unique. Otherwise generated json will be invalid. That means If we have two paths /somepath and /somepath/{id} with same request type RequestDto we must define two operations for each path with distinguished name. In this case we generate two OperationIds RequestDto and RequestDtoId to avoid name duplication.

Secondly for every verb we must generate operation as well, so we add _{verb} to the end of the OperationId to make it unique. Also Autorest client generator checks that OperationId has the _{verb} at the end of operation and shows a validation error message and generates wrong client when this is not true.

So with Open API is difficult to get original request type from OperationId if you don’t know the name type you are looking for and Open API does not provide any special fields in json which can be used to handle original type. You can possible get type info if examine body parameter and retrieve the Schema property but body is present only for POST/PUT verbs. Also, for generic types schema does not contain the full info.

So the determining the type using RestHandler which is used in your example is the much better way than trying to get the original type directly from specification.