Luca P.
Luca P.

Reputation: 1071

Openapi 3.0 and endpoints that support both GET and POST

I have a handmade REST API that I would like to retrofit to use Openapi 3.0.0

One of my (hand-made Python/Flask) endpoints supports both GET and POST methods in one shot:

@app.route('/search', methods=['POST','GET'])
def searchDevices():

    if request.method == 'GET':
        brand = request.args.get('brand')
        model = request.args.get('model')
        capas = request.args.get('capabilities')
    elif request.method == 'POST':
        brand = request.form.get('brand')
        model = request.form.get('model')
        capas = request.form.get('capabilities')

Is there a way to model this in Openapi 3.0.0? Right now I understand that I'll need to define to separate YAML end-points with a lot of repetions (bye-bye, DRY), but maybe I am missing something. It would be cool if I could do something like:

paths:
  /search:
    parameters:
      - schema:
         :
    get, post:

but alas this doesn't seem to work at the moment.

Upvotes: 1

Views: 2416

Answers (1)

Helen
Helen

Reputation: 97540

An endpoint that honors parameters no matter if they are sent through the GET or POST method.

This can be modeled with OpenAPI, but requires a little bit of repetition because: a) different HTTP methods (GET, POST, etc.) must be defined as separate operations; b) query string and request body are represented by different keywords.

To reuse the POST request body schema for the GET query string, you need to define the entire query string as a single object-type parameter with style: form + explode: true as the serialization style. This means that the object is converted to key=value pairs when sent in the query string.

The API definition would look like this:

openapi: 3.0.3
...

paths:
  /search:
    get:
      parameters:
        - in: query
          name: params  # Arbitrary name, not used in the request URL
          schema:
            $ref: '#/components/schemas/SearchParams'
          
          # This is the default serialization style for query parameters
          # so these keywords can be omitted
          style: form
          explode: true
      responses:
        '200':
          description: OK
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchParams'
      responses:
        '200':
          description: OK

components:
  schemas:
    SearchParams:
      type: object
      properties:
        brand:
          type: string
        model:
          type: string
        capabilities:
          type: string

Upvotes: 1

Related Questions