apigee-127/sway

Spec with duplicated paths but different methods should be valid

Closed this issue ยท 22 comments

Following is valid Swagger:

{
  "info": {
    "title": "test",
    "version": "1.0.0",
  },
  "paths": {
    "/{arg1}": {
      "get": {
        "parameters": [
          {
            "name": "arg1",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": { "description": "OK" }
        }
      }
    },
    "/{arg2}": {
      "head": {
        "parameters": [
          {
            "name": "arg2",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": { "description": "OK" }
        }
      }
    }
  },
  "swagger": "2.0"
}

But currently it throws an error:

[
  {
    "code": "EQUIVALENT_PATH",
    "message": "Equivalent path already exists: /{arg2}",
    "path": [
      "paths",
      "/{arg2}"
    ]
  }
]

P.S. I have PR, but I submit issues just to mark it properly in tests.

They are not two different paths :)

As @mohsen1 said, they are not different paths. There is no way to tell whether /foo and /bar should go to /{arg1} or /{arg2}. At best you could do some type-based decision but in reality, the path is the same regardless. I'll keep it open for discussion but I don't think we'll be supporting this.

Spec with duplicated paths but different methods should be valid
@whitlockjc @mohsen1 Yes, paths exactly the same but one have get method and another have head method.
So no conflict during call.

By the way swagger-tools have same issue.

Of course it does, they treat equivalent paths the same. I'm saying that since they are equivalently the same, although not identical from a definition perspective, it doesn't matter. Sure, we could possibly support it but I don't know why you'd want to. Why not just collapse the different methods into one path?

@whitlockjc Because you use different path arguments, with different names, types, descriptions. I have examples of such file from web scraping that I do. So people really use this feature and it valid according to Swagger spec.

@webron Can you tell me how Swagger should handle paths that are lexically unique but functionally equivalent? Take for example /pet/{petId} and /pet/{id}...to me and any other path-based router/matcher out there, they are equivalent. But I'd love your opinion.

That's an invalid definition. The two paths are indeed identical as far as Swagger is concerned.

@whitlockjc Yes, they are equivalent but set of methods is different, so router can function properly.
So you should think of pairs ["/pet/{petId}", "GET"] and ["/pet/{id}", "HEAD"], and there are no conflicts.
@webron I couldn't find anything in spec that forbid this behaviour. It also used in APIs and even in swagger specs.

@IvanGoncharov - sure, we can definitely clarify that in the spec, but it is definitely not supported.

I opened documentation issue in swagger-spec repo.

Thanks.

โœ– Swagger Error
Equivalent path already exists: /profile/address/{id}

โœ– Swagger Error
Equivalent path already exists: /profile/qualifications/{id}

whats wrong here? these are totally different.

Can you give me a spec with a reproduction scenario?

cskru commented

Ofcourse!
I am scratching my head regarding this and I created a spec to reproduce.

Spec1: paste this spec on https://editor.swagger.io/

info:
  title: Server
  version: 1.0.0

host: 'localhost:8000'
basePath: /
produces:
  - application/json

schemes:
  - http

swagger: '2.0'
paths:
  
  '/path/{paramName}':
    get:
      summary: Get paramName
      parameters:
        - name: paramName
          in: path
          required: true
          type: string
      responses:
        '200':
          description: Success
  '/path/{someOtherParamNameButTheVerbIsPut}':
    put:
      summary: Update paramName
      parameters:
        - name: someOtherParamNameButTheVerbIsPut
          in: path
          required: true
          type: string
      responses:
        '200':
          description: Success

Please reopen this issue or may be I can file a separate issue

/path/{paramName} and /path/{someOtherParamButTheVerbIsPut} is functionally the same. So /path/foo will match both of those paths and I think that is an oversight. I'm not sure there is anything in the OAS 2.0 spec that says this is an error but I cannot think of why anyone would want to do this. Maybe @webron has an opinion.

It's an error, the two paths are considered identical.

There you have it. Thanks @webron!

can someone explain what the purpose of this is restriction is? as mentioned above the unique identifier for a resource is verb + path

@pbarker correct, and /path/{a} and /path/{b} are the same path.

Five years later... how should one define the following operations in swagger?:

GET    /user/{id}    // Get user
PUT    /user/{id}    // Update user
DELETE /user/{id}    // Remove user

It's quite simple:

# ...
paths:
  /user/{id}:
    delete:
      # Operation details for DELETE
    get:
      # Operation details for GET
    put:
      # Operation details for PUT
# ...

The Paths Object and Path Item Object documentation should explain.

Also, next time...please start a new issue when asking for help, especially when the issue you commented on is unrelated to the question being asked. (Your question is unrelated because you have 3 operations for the same path and the issue is about how OpenAPI treats paths that are technically different but functionally the same.)