falcon-apispec icon indicating copy to clipboard operation
falcon-apispec copied to clipboard

Fix/expose only supported methods

Open AndreasBBS opened this issue 2 years ago • 1 comments

Expose only implemented methods

Make this Plugin list only implemented methods instead of all possible methods

Example:

For the path defined by the class:

import falcon
from schemas.Pet import PetSchema

from app import app, spec

from random import randint, choices
from string import ascii_uppercase, digits

class RandomPetResource:
    async def on_get(self, req, resp):
        """A cute furry animal endpoint.
        ---
        description: Get a random pet
        responses:
            200:
                description: A pet to be returned
                schema: PetSchema
        """
        pet = {
            "id": randint(1, 100),
            "name": ''.join(
                choices(ascii_uppercase + digits, k=10)
            )
        }
        resp.media = PetSchema().dump(pet)
        resp.status = falcon.HTTP_200

# Register Pet Resource
pets = RandomPetResource()
app.add_route('/pet', pets)
spec.path(resource=pets)

Before the fix, the resulting swagger.json looks like:

{
  "paths": {
    "/pet": {
      "get": {
        "description": "Get a random pet",
        "responses": {
          "200": {
            "description": "A pet to be returned",
            "schema": {
              "$ref": "#/components/schemas/Pet"
            }
          }
        }
      },
      "options": {},
      "delete": {},
      "head": {},
      "patch": {},
      "post": {},
      "put": {},
      "trace": {}
    }
  },
  "info": {
    "title": "TenScores API",
    "version": "0.0.1"
  },
  "openapi": "3.0.2",
  "components": {
    "schemas": {
      "Pet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ]
      }
    }
  }
}

After the fix, the resulting swagger.json looks like:

{
  "paths": {
    "/pet": {
      "get": {
        "description": "Get a random pet",
        "responses": {
          "200": {
            "description": "A pet to be returned",
            "schema": {
              "$ref": "#/components/schemas/Pet"
            }
          }
        }
      }
    }
  },
  "info": {
    "title": "TenScores API",
    "version": "0.0.1"
  },
  "openapi": "3.0.2",
  "components": {
    "schemas": {
      "Pet": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "id": {
            "type": "integer"
          }
        },
        "required": [
          "name"
        ]
      }
    }
  }
}

It's also more efficient because, instead of going through all the routes and creating a mapping for each resource every time spec.path gets called, it filters for the route with the passed resource.

Feel free to try my changes by using pip install git+https://github.com/AndreasBBS/falcon-apispec.git@fix/expose_only_supported_methods#egg=falcon-apispec

NOTE: I'm also including the changes in this PR https://github.com/alysivji/falcon-apispec/pull/32 that's taking ages to get merged cause I couldn't be bothered to change falcon to a version prior to 3.0

AndreasBBS avatar Dec 05 '22 21:12 AndreasBBS

@alysivji @aslantar @Javlopez Forgot to put you as reviewrs and can't do it now. Please set yourselves. I'd love to hear back if you think this is useful too.

AndreasBBS avatar Dec 08 '22 04:12 AndreasBBS