Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenAPI / Swagger model inheritance with AWS API Gateway

I'm attempting to implement an API defined in Swagger or OpenAPI 3.0 using AWS API Gateway.

One endpoint in this API takes an abstract base model (lets call it Pet to be consistent with the well-worn Swagger example), but actually expects a concrete model that is derived from Pet... Dog for example.

The concrete model can be determined by a type attribute on Pet.

The concrete model can add additional fields.

Of course, this a job for a discriminator:

definitions:
    Pet:
        discriminator: petType
        required:
        - name
        - petType # required for inheritance to work
        properties:
        name: 
            type: string
        petType:
            type: string
    Cat:
        allOf:
        - $ref: '#/definitions/Pet' # Cat has all properties of a Pet
        - properties: # extra properties only for cats
            huntingSkill:
                type: string
                default: lazy
                enum:
                - lazy
                - aggressive
    Dog:
        allOf:
        - $ref: '#/definitions/Pet' # Dog has all properties of a Pet
        - properties: # extra properties only for dogs
            packSize:
                description: The size of the pack the dog is from
                type: integer

(taken from here)

However, AWS API Gateway doesn't support discriminator (ref).

OK, annoying, but maybe a workaround is to define the API with OpenAPI 3.0, and utilise oneOf in the schema:

paths:
    /pets:
        patch:
            requestBody:
                content:
                    application/json:
                        schema:
                            oneOf:
                                - $ref: '#/components/schemas/Cat'
                                - $ref: '#/components/schemas/Dog'

However (again), AWS API Gateway doesn't support oneOf either (ref).

Does anyone know how to implement a model schema of this nature with AWS API Gateway, in particular to take advantage of body validation for an inheritance pattern (Pet <- Dog)? Or indeed a workaround without having to have methods for every concrete type?

like image 758
KevinD Avatar asked Nov 18 '19 18:11

KevinD


People also ask

Does AWS API gateway support Swagger?

Amazon API Gateway now supports importing Swagger API definitions. Previously, you would use the Swagger importer tool to import Swagger definitions into API Gateway. Now, you can import your Swagger API definitions into API Gateway through the AWS Management Console, CLI, and SDK.

Can Swagger documentation be used for AWS API gateway setup?

You can connect your API definitions in SwaggerHub to API Gateway by using the Amazon API Gateway integration. The integration will push your API definition to API Gateway every time you save it in SwaggerHub. This way you can quickly create or update an API in API Gateway from SwaggerHub.


Video Answer


1 Answers

This may not be fully satisfactory answer to your question, but there is a way to use oneOf with API Gateway. You can use JSON schema for individual models according to AWS.

Thanks to that fact you can update your models after API Gateway has been deployed.

# Reformatted here for readability
VALUE='"{\"$schema\": \"http://json-schema.org/draft-04/schema#\",
         \"title\": \"A Pet Request\",
         \"oneOf\":
        [{ \"$ref\": \"https://apigateway.amazonaws.com/restapis/xxxxxxx/models/Cat\" },
         { \"$ref\": \"https://apigateway.amazonaws.com/restapis/xxxxxxx/models/Dog\" }]}"'


aws apigateway update-model \
--rest-api-id xxxxxxx \
--model-name 'PetRequest' \
--patch-operations "op=replace,path=/schema,value=${VALUE}"

This solution works, however might not be greatly sustainable, since you need to execute the patch-operations after each deployment.

I'll likely update this answer if I find better way.

like image 111
sireliah Avatar answered Oct 29 '22 13:10

sireliah