LazyStack

OpenAPI Specification (formerly Swagger)

"The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic." OpenAPI Specification

The core idea behind LazyStack is that most of the plumbing between the app client and app server logic (in this case AWS Lambda functions) is code that can be easily generated. When combined with a "sensible" specification of AWS resources, it is straight forward to generate a AWS Serverless Stack and the required ClientSDK directly from an OpenAPI specification.

The OpenAPI specification is widely used, simple to read and a wide variety of tools exist to make authoring a compliant OpenAPI document straight forward. Check out the Swagger Editor for a very competent tool for authoring your APIs.

A wide variety of OpenAPI → C# generators exist. We have used quite a few and at the end of the day decided to include the NSwag generator in LazyStack. It is reasonably robust and is written in C# which makes it a natural fit for our .NET focused tool-chain.

PetStore.yaml

Throughout the LazyStack documentation, we use a OpenAPI specification document PetStore.yaml. This simple API exercises many of the important features we want to illustrate and which are relevant for many application stacks. This PetStore.yaml is very similar to the PetStore.yaml used by swagger.io in their documentation of the standard. One of the most important features of the OpenAPI specification is the ability to associate "tags" with each path. We use this tags feature to group paths and then generate a single Lambda for each tag. We cover this feature in detail later on but as you read through the specification below, you should note how each path is assigned to one of the four defined tags: pet, petSecure, order and orderSecure.

Each path in your OpenAPI specification should have a single tag assignment and an operationId. These are both optional OpenAPI elements but they are necessary for LazyStack stack generation.

openapi: 3.0.0
info:
  description: |
    This is a sample Petstore server.  You can find
    out more about Swagger at
    [http://swagger.io](http://swagger.io) or on
    [irc.freenode.net, #swagger](http://swagger.io/irc/).
  version: "1.0.0"
  title: Swagger Petstore
  termsOfService: 'http://swagger.io/terms/'
  contact:
    email: apiteam@swagger.io
  license:
    name: Apache 2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: pet
- name: petSecure
- name: order
- name: orderSecure
paths:         
  /pet:
    post:
      tags:
      - petSecure
      summary: Add a new pet to the store
      operationId: addPet
      responses:
        '405':
          description: Invalid input
      requestBody:
        $ref: '#/components/requestBodies/Pet'
    put:
      tags:
      - petSecure
      summary: Update an existing pet
      operationId: updatePet
      responses:
        '400':
          description: Invalid ID supplied
        '404':
          description: Pet not found
        '405':
          description: Validation exception
      requestBody:
        $ref: '#/components/requestBodies/Pet'

  /pet/findByStatus:
    get:
      tags:
      - pet
      summary: Finds Pets by status
      description: Multiple status values can be provided with comma separated strings
      operationId: findPetsByStatus
      parameters:
      - name: petStatus
        in: query
        description: Status values that need to be considered for filter
        required: true
        explode: true
        schema:
          type: array
          items:
            $ref: '#/components/schemas/PetStatus'
          default: available
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
        '400':
          description: Invalid status value

  '/pet/{petId}':
    get:
      tags:
      - pet
      summary: Find pet by ID
      description: Returns a single pet
      operationId: getPetById
      parameters:
      - name: petId
        in: path
        description: ID of pet to return
        required: true
        schema:
          type: integer
          format: int64
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'
        '400':
          description: Invalid ID supplied
        '404':
          description: Pet not found
    post:
      tags:
      - petSecure
      summary: Updates a pet in the store with form data
      operationId: updatePetWithForm
      parameters:
      - name: petId
        in: path
        description: ID of pet that needs to be updated
        required: true
        schema:
          type: integer
          format: int64
      responses:
        '405':
          description: Invalid input
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                name:
                  description: Updated name of the pet
                  type: string
                status:
                  description: Updated status of the pet
                  type: string
    delete:
      tags:
      - petSecure
      summary: Deletes a pet
      operationId: deletePet
      parameters:
      - name: api_key
        in: header
        required: false
        schema:
          type: string
      - name: petId
        in: path
        description: Pet id to delete
        required: true
        schema:
          type: integer
          format: int64
      responses:
        '400':
          description: Invalid ID supplied
        '404':
          description: Pet not found
  /pet/categories:
    get:
      tags:
      - pet
      summary: Get all Pet Categories
      operationId: getPetCategories
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Category'
  /pet/tags:
    get:
      tags:
      - pet
      summary: Get all Pet Tags
      operationId: getPetTags
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Tag'

  /order/inventory:
    get:
      tags:
      - orderSecure
      summary: Returns pet inventories by status
      description: Returns a map of status codes to quantities
      operationId: getInventory
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: integer
                  format: int32
  /order:
    post:
      tags:
      - order
      summary: Place an order for a pet
      operationId: placeOrder
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
          description: Invalid Order
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Order'
        description: order placed for purchasing the pet
        required: true
  '/order/{orderId}':
    get:
      tags:
      - order
      summary: Find purchase order by ID
      description: >-
        For valid response try integer IDs with value >= 1 and <= 10.\ \ Other values will generated exceptions
      operationId: getOrderById
      parameters:
      - name: orderId
        in: path
        description: ID of pet that needs to be fetched
        required: true
        schema:
          type: integer
          format: int64
          minimum: 1
          maximum: 10
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
          description: Invalid ID supplied
        '404':
          description: Order not found
    delete:
      tags:
      - orderSecure
      summary: Delete purchase order by ID
      description: >-
        For valid response try integer IDs with positive integer value.\ \ Negative or non-integer values will generate API errors
      operationId: deleteOrder
      parameters:
      - name: orderId
        in: path
        description: ID of the order that needs to be deleted
        required: true
        schema:
          type: integer
          format: int64
          minimum: 1
      responses:
        '400':
          description: Invalid ID supplied
        '404':
          description: Order not found
  /pet/findByTags:
    get:
      tags:
      - pet
      summary: Finds Pets by tags
      description: >-
        Muliple tags can be provided with comma separated strings. Use\ \ tag1, tag2, tag3 for testing.
      operationId: findPetsByTags
      parameters:
      - name: tags
        in: query
        description: Tags to filter by
        required: true
        explode: true
        schema:
          type: array
          items:
            type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
        '400':
          description: Invalid tag value
      deprecated: true
  /pet/seedPets:
    get:
      tags:
      - pet
      summary: See pet database
      operationId: seedPets
      responses:
        '200':
          description: successful operation

components:
  schemas:
    Order:
      type: object
      properties:
        id:
          type: integer
          format: int64
        userId:
          type: string
          description: Cognito Identity Id of clerk entering order
        petId:
          type: integer
          format: int64
        quantity:
          type: integer
          format: int32
        shipDate:
          type: string
          format: date-time
        orderStatus:
          type: string
          title: orderStatus
          description: Order Status
          $ref: '#/components/schemas/OrderStatus'
        complete:
          type: boolean
          default: false
        createUtcTick:
          type: integer
          format: int64
        updateUtcTick:
          type: integer
          format: int64

    OrderStatus:
      type: string
      description: Order Status
      enum:
      - placed
      - approved
      - delivered

    Category:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
    Tag:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
    Pet:
      type: object
      required:
      - name
      - photoUrls
      properties:
        id:
          type: integer
          format: int64
        category:
          $ref: '#/components/schemas/Category'
        name:
          type: string
          example: doggie
        photoUrls:
          type: array
          items:
            type: string
        tags:
          type: array
          items:
            $ref: '#/components/schemas/Tag'
        petStatus:
          type: string
          description: pet status in the store
          $ref: '#/components/schemas/PetStatus'
        createUtcTick:
          type: integer
          format: int64
        updateUtcTick:
          type: integer
          format: int64

    PetStatus:
      type: string
      description: pet status in the store
      enum:
      - available
      - pending
      - sold
      
  requestBodies:
    Pet:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Pet'
      description: Pet object that needs to be added to the store
      required: true