API-Designer: Duplicate operationIds in the swagger definition

When we define API methods like

builder.AddMethod(Method.Define("obj").HandleGet(qr => "list of objs"));
builder.AddMethod(Method.Define("obj/{id}").WithParameter("id", isInQuery: false).HandleGet(qr => "single obj"));

we encounter the error message (while compiling):

Duplicate operationIds in the swagger definition
	at VI.ApiDesigner.CodeGen.SwaggerGen.<DoAsync>d__4.MoveNext()
	at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	at CompositionApiToSwagger.SwaggerDocumentContainer.<CreateAsync>d__7.MoveNext()
	at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	at CompositionApiToSwagger.SwaggerDocumentContainer.<AddRoutesAsync>d__9.MoveNext()

I tried to remove the first definition and treat the empty id inside the handler - but then the "empty" call "/obj/" does not exists anymore (404) - even with an arbitrary default value. So I think this is broken.

Is there another way to define the methods as described (even swagger defines that as best practice https://swagger.io/resources/articles/best-practices-in-api-design/ ) - so I think the error comes from a step before.

Parents
  • It's the same for two methods with different count of parameters, e.g.

    builder.AddMethod(Method.Define("obj/{id}").WithParameter("id", isInQuery: false).HandleGet(qr => "single obj"));
    builder.AddMethod(Method.Define("obj/{id}/{id2}").WithParameter("id", isInQuery: false).WithParameter("id2", isInQuery: false).HandleGet(qr => "single sub-obj"));

    I investigated a bit further and it seems that every part of the path that is like {...}, is ignored in the generation of the operationId (in the generated swagger.json).
    Thus the above definitions both lead to the operationId "CCC_obj_get"..

  • Hi,

    The {...} parts of your path are not exactly ignored, but as they are parameters, they are not part of the method name.

    In your situation, the two methods lead to the same operation ID.

    The best thing to do is to disambiguate the methods by assigning a ClientSuffix:

    Method.Define("obj/{id}/{id2}")
    ...
    .With(m => m.Settings.ClientSuffix = "byid")

    This will cause the TypeScript generator to create an operation ID "CCC_obj_get_byid".

    Regards

    Hanno

Reply
  • Hi,

    The {...} parts of your path are not exactly ignored, but as they are parameters, they are not part of the method name.

    In your situation, the two methods lead to the same operation ID.

    The best thing to do is to disambiguate the methods by assigning a ClientSuffix:

    Method.Define("obj/{id}/{id2}")
    ...
    .With(m => m.Settings.ClientSuffix = "byid")

    This will cause the TypeScript generator to create an operation ID "CCC_obj_get_byid".

    Regards

    Hanno

Children