unique operationId

48 views
Skip to first unread message

jmls

unread,
Sep 24, 2016, 2:05:52 PM9/24/16
to Swagger
Hey all

Been looking through the v2 specification (http://swagger.io/specification/) , and came across this statement:

operationId: Unique string used to identify the operation. The id MUST be unique among all operations described in the API. Tools and libraries MAY use the operationId to uniquely identify an operation, therefore, it is recommended to follow common programming naming conventions.

I am slightly confused about this : 

if I have 2 models (Customer and Order) does this mean that a "find" method must be unique across both, or just within the model ? (ie is the API the model or all models ? )

So I tried an experiment: I have 2 operationId's of "find" : 1 on the customer and one on the order

I then ran swagger codegen and it didn't complain about uniqueness. 

I then added *another* "find" to the Customer model, and this time codegen did complain about non-unique operationid's - and renamed it to find_1

So - is swagger-codegen wrong, or are operationId's unique within a model and not the whole API ?

Thanks

tony tam

unread,
Sep 26, 2016, 10:08:56 PM9/26/16
to swagger-sw...@googlegroups.com
Hi, you should have unique numbers for all operationId values.  If the tools work, it doesn’t make it right—it just means they’re being lenient.  They could throw errors but the authors have decided to gracefully handle the error in the spec.

--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

jmls

unread,
Sep 27, 2016, 4:22:55 AM9/27/16
to Swagger
thanks for the reply, Tony

can I just clarify something : you said " you should have unique numbers for all operationId values" , so does that mean a guid / uuid would be acceptable ? If so, how do you *name* the endpoint ?

This is perhaps where my confusion is coming from. I completely understand the requirement for operationId to be unique, but is there a name / nickname / alias property I can use to name the method ? I've only seen an operationid containing a "meaningful" (ie getPet) value rather than a number / id / guid etc

Thanks
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

tony tam

unread,
Sep 27, 2016, 10:32:04 AM9/27/16
to swagger-sw...@googlegroups.com
Hi, indeed you can use numbers or a guid. Just keep in mind that tooling (swagger-ui or codegen) may need to coerce that string to something appropriate (i.e. you can’t typically have hyphens in a method name for client SDKs).

Also… since that field is optional you can choose to not supply it at all—then the consumer has to invent something on its’ own.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

jmls

unread,
Sep 27, 2016, 11:44:56 AM9/27/16
to Swagger
This brings me back to the original point: if I have 2 models, Customer and Order, and they each have a "find" method, I would like the sdk to be

Customer.find() and Order.find()

At the moment, because the operationId is Customer_find and Order_find, the actual method names are

Customer.CustomerFind() and Order.OrderFind() which looks ugly

if I used guid1 and guid2 as the operationids, then the models are Customer.guid1() and Order.guid2() which is also ugly ;)

Is there an "alias" or "methodname" property in the spec that would allow me to have a unique operationId, but a method name of "find" (in this
particular case) ?

Julian

tony tam

unread,
Sep 27, 2016, 12:00:04 PM9/27/16
to swagger-sw...@googlegroups.com
I think we’re confusing concepts here.  Operations have operationIds.  If you’re talking about models, I’m assuming you’re talking about definitions or payloads to/from the operation.

An operation is the combination of a HTTP method and a path, such as:

GET: /pets/3

A model is a payload defined in JSON schema.  An instance of a model may look like this:

{
  “id”: 3
  “name”: “dog”
}

A model definition is a subset of JSON schema, it looks like this:

definitions: {
  “Pet”: {
    “properties”: {
      “id”: {
        “type”: “integer”,
        “format”: “int32”
      }
    }
  }

So there is no operationId on a model, only an operation.  And in the specification, there are no operations on models—but code generators may implicitly add them, depending on the language.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

jmls

unread,
Sep 27, 2016, 12:33:12 PM9/27/16
to Swagger
Yes, I was confused.  Easily done :)

Still - is there a way of passing / using a name instead of an operationId to the client sdk generator ? Or is that a feature that the client sdk will have to cater for ?

If there isn't a way, if I were to add a "x-method-name" property to the swagger spec file for that operation and modify the client sdk to use the value of x-method-name if it existed, would that be the most appropriate way ?

thanks

jmls

unread,
Sep 27, 2016, 12:37:17 PM9/27/16
to Swagger
for example, the node-typescript generator has this template snippet :

{{#operation}}
   /**
    * {{summary}}
    * {{notes}}
    {{#allParams}}* @param {{paramName}} {{description}}
    {{/allParams}}*/
   public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : Promise<{ response: http.{{#supportsES6}}IncomingMessage{{/supportsES6}}{{^supportsES6}}ClientResponse{{/supportsES6}}; {{#returnType}}body: {{{returnType}}}; {{/returnType}}{{^returnType}}body?: any; {{/returnType}} }> {


where the {{nickname}} is the method - this is seemingly generated from the operationid, but I'm kinda hoping that there's a way of changing / defining the "nickname"

tony tam

unread,
Sep 27, 2016, 1:03:57 PM9/27/16
to swagger-sw...@googlegroups.com
OK great, we’re talking the same language now :)

For compatibility reasons between spec versions 1.x and 2.0 the term nickname maps 1:1 to operationId

Overriding the nickname is easy, but it’s done in the java code for TypeScript, not the templates.  You can easily pass an extension like x-operationId if you wanted to use that, and tell the code generator to select that operation id if it exists.  It’d require some java, though, or perhaps a really nice request for help in the swagger-codegen issues

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

jmls

unread,
Sep 27, 2016, 1:12:43 PM9/27/16
to Swagger
I'm not a java guy .. but something along the lines of

line 2072 of swagger-codegen/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java
op.nickname = op.operationId;
could become

op.nickname = Objects.toString(p.vendorExtensions.get("x-methodname")) || op.operationId;
?
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages