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

Meaning of the term API in the operationId context. #381

Open
bachp opened this issue May 27, 2015 · 12 comments
Open

Meaning of the term API in the operationId context. #381

bachp opened this issue May 27, 2015 · 12 comments
Assignees
Labels
re-use: ref/id resolution how $ref, operationId, or anything else is resolved

Comments

@bachp
Copy link

bachp commented May 27, 2015

In the context of an operationId. the spec says:

The id [operationId] MUST be unique among all operations described in the API

What is the definition of API in this context?
Does it mean all operations defined in the same file?
All operations used by an application?

Did I just miss the definition or should this be clarified?

@webron
Copy link
Member

webron commented May 27, 2015

That's a fair question and needs to be clarified.

The 'basic' limitation would be within the same Swagger description. The real challenge is how it would behave when referencing external files.

@jfiala
Copy link

jfiala commented Mar 18, 2016

If I understand this correctly, the operationId currently has to be unique for each API endpoint an application provides. If it provides multiple API endpoints, the operationId is only required to be unique per API endpoint.

Currently I use Swagger Springfox/Swagger Codegen to generate code and I get one API class for each controller class (tag). IMHO in fact, it would be totally sufficient to demand that the operationId is unique per RequestMapping path/tag/controller/API class.

What the current interpretation of the specification leads to is that the operationId is suffixed with numbers to guarantee its uniqueness.

Request Paths:
/pet/find
/category/find
/person/find

Generated API definition (provided by Swagger Springfox):
"/pet/find": operationId: findUsingGET
"/category/find": operationId: findUsingGET_1
"/person/find": operationId: findUsingGET_2

The generated code using Swagger Codegen then looks like this:
PetAPI.findUsingGET()
CategoryAPI.findUsingGET_1()
PersonAPI.findUsingGET_2()

So in fact, although IMHO it would be totally sufficient to scope the uniqueness of the operationId per tag/API class, it is now suffixed and generates hardly understandable client code with lots of suffixes.

The current solution to this is to use nicknames for the operations and name them uniquely:
"/pet/find": operationId: pet_findUsingGET
"/category/find": operationId: category_findUsingGET
"/person/find": operationId: person_findUsingGET

This solution is unsatisfying so far that it adds a scoping to methods that are already scoped:
PetAPI.pet_findUsingGET()
CategoryAPI.category_findUsingGET()
PersonAPI.person_findUsingGET()

Wouldn't it be sufficient to demand that the operationId is unique per tag it is associated to (or per Request Path)?

@RobThree
Copy link

RobThree commented Jan 21, 2019

I wonder what use the OperationId has. I am struggling, as many are, with "Cannot have multiple operations with the same operationId ", and have seen all sorts of solutions like this one to generate OperationId's.

So here's a thought... what if I simply get rid of the OperationId? Or what if I generate an SHA1 hash for the OperationId (based on some context so the Id is 'stable' across builds / versions). What if I simply assign an incrementing number (operation_1, operation_2) etc. for the OperationId? I understand that such Id's might not be as descriptive as GetPetByName OperationId's but, as long as the OperationId is only used by machines and isn't exposed to users by tooling etc, then why not have a SHA1 hash or whatever for an OperationId (as long as I can guarantee it's stable)? And, again, do we even need an OperationId in the first place? AFAIK: "An operationId can be added"; it isn't mandatory, is it?

@MikeRalphson
Copy link
Member

MikeRalphson commented Jan 21, 2019

what if I simply get rid of the OperationId? It isn't mandatory, is it?

No. And if present, they can be anything you wish, including unique integers, hashes etc. Some tooling, especially code-generation tools may make use of operationIds to generate (say) routing controller names.

@RobThree
Copy link

RobThree commented Jan 21, 2019

Exactly, that's what I gathered. But I guess my question is: is it used "in the field"? Is there tooling or whatever that's dependent on the OperationId? (Edit: apparently there is; you added another sentence to your post 😉 ) Is it better to provide an OperationId (be it a hash or integer or string like GetPetByName) to better assist tooling or should leaving it out have negligible effects? And should I choose anything other than the, what seems to be commonly used, GetPetByName-like operation ID's, what will the consequences be of having non-descriptive "ID's"?

But so far I'm considering removing OperationID's alltogether from my swagger document.

@MikeRalphson
Copy link
Member

Yes, I would personally recommend providing a descriptive operationId if you can, in case your OpenAPI document is ever used for code-generation. The consequence would be less readable generated code / debugging / errors etc.

@handrews
Copy link
Member

@MikeRalphson Operation IDs are primarily for use in Link Objects, right?

@MikeRalphson
Copy link
Member

I'd not say primarily, as they predate the presence of links in the spec., but that is another use as a shorthand for path + method.

@darrelmiller
Copy link
Member

Tooling uses OperationId fairly extensively. Readable OperationIds are generally preferred as it makes it easier to hand edit documents.

@bobvanderlinden
Copy link

bobvanderlinden commented Feb 8, 2019

I personally think the operationId has its use (unique identifier for operations). However, I think it is being misused in many cases.

One tool that is misusing it is the codegen. It uses the operationId for method name and uses the tag(s) for classname. The method names do not need to be unique across all classes for all languages I know of. This becomes especially awkward when the operationId is generated from existing code (like Java) where methods do not need to be unique across all classes. Perfectly reasonable looking Java code is incorrect because methods names are now suddenly unique across classes.

For codegen it would be nice if we could just specify what the classname and methodname should be, separate from the operationId.

For Swagger-UI the operationId is correctly used IMO. It isn't being shown as a kind of 'short name'. It is actually a unique identifier just to reference a specific operation. The operation can be referenced using the # in the URL and (from what I gathered) is used internally to reference JS/HTML elements.

A UUID in this case makes perfect sense and seems more stable than a user-defined Id that needs to look good in order to use it as a method name.

@joanjames-zebra
Copy link

Besides codegen and apigee SmartDocs, which tools actually use the operationId?

We started with title case and spaces between words in the operationId for SmartDocs rendering which uses the operationId for titles. Now it seems the spaces may cause trouble in other tools. According to the OpenAPI Spec definition of the operationId ' .. it is RECOMMENDED to follow common programming naming conventions'.

Now I am wondering if we should convert the operationId to Camel Case or hyphenated words? The operationId is being ignored by our current rendering. The summary and description are being used.

What is the best practice for the operationId?

@bobvanderlinden
Copy link

What we are doing is create operationIds from classname and method name. For instance something like: UserController.byId. That way it is unique and human-readable. However, when we're passing the specs to a codegen, then we're transforming the specs so that the tag of the operation becomes User and the operationId becomes byId.

This results in general use we have a valid specification. For codegen we have an invalid specification (byId is not unique), but it will at least work for the codegen.

I wouldn't call it 'best practice', but it is how we're coping with this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
re-use: ref/id resolution how $ref, operationId, or anything else is resolved
Projects
None yet
Development

No branches or pull requests

9 participants