Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

serverless-aws-documentation model definitions with optional fields?

I want to define request and response models. I use the Serverless Framework with AWS and everything I'm seeing recommends using serverless-aws-documentation

The README says that I need to have this line in custom.documentation.models.MODELNAME

schema: ${file(models/error.json)}

But they don't have an example file of models/error.json to use as a baseline.

In the actual example serverless.yml they have a definition like this:

-
  name: DoSomethingRequest
  contentType: "application/json"
  schema:
    type: array
    items:
      type: string

This doesn't provide enough detail for what I'm trying to do.


My goal is to have a schema defined for an array of string objects, a message and a status code. The message and status code, though, are optional. These could also be part of other models and if possible I'd like to not repeat their definition for each model.

My current attempt is:

-
  name: ReturnArrayResponse
  contentType: "application/json"
  schema:
    type: array
    itemsArray:
      type: string
    message:
      type: string
    statusCode:
      type: number

I think this is going to do what I want, but how can I have message and statusCode be optional and repeat these two items in my other models?

I'd be happy with either a yml solution I can put in my serverless.yml file or a json file that I can reference.

like image 550
Serverless chap Avatar asked Nov 15 '17 06:11

Serverless chap


People also ask

Which resources can be specified in the AWS serverless application model?

Note that a serverless application is more than just a Lambda function—it can include additional resources such as APIs, databases, and event source mappings. You can use AWS SAM to define your serverless applications.

What does the AWS serverless application model template specification provide to help deploy your serverless application on AWS?

The AWS Serverless Application Model (SAM) is an open-source framework for building serverless applications. It provides shorthand syntax to express functions, APIs, databases, and event source mappings. With just a few lines per resource, you can define the application you want and model it using YAML.

What are AWS serverless components?

Serverless technologies feature automatic scaling, built-in high availability, and a pay-for-use billing model to increase agility and optimize costs. These technologies also eliminate infrastructure management tasks like capacity provisioning and patching, so you can focus on writing code that serves your customers.

How do I refer to a property in serverless YAML file?

To reference properties in other YAML files use the ${file(./myFile. yml):someProperty} syntax in your serverless. yml configuration file. To reference properties in other JSON files use the ${file(./myFile.


1 Answers

Including a file

In the example given, error.json can contain any valid schema. So something as simple as this is fine:

{"type":"object","properties":{"message":{"type":"string"}}}

It's also fine to include attributes like $schema and title:

{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "Error Schema",
  "type" : "object",
  "properties" : {
    "message" : { "type" : "string" },
    "statusCode": { "type": "number" },
    "itemsArray": {
        "type": "array",
        "items": {
            "type": "string"
        }
    }
  }
}

This is especially handy when you have models already defined in AWS, but you don't have the serverless yaml to build them. You can simply copy the schema out of the AWS console, paste the json into a file, and use the schema: ${file()} syntax mentioned in the question. As far as I can tell anything that you can get the AWS console to accept will work.

DRY

I don't know of a way to reference models from within other models in a serverless file, but you could use the same approach as the plugin authors, and just put anything you need to reuse outside of the models and somewhere it's easier to reuse. The plugin authors use commonModelSchemaFragments.

So if you have some fragments like so:

  commonModelSchemaFragments:
    # defining common fragments means you can reference them with a single line
    StringArrayFragment:
        type: array
        items:
          type: string
    HttpResponse:
      type: object
      properties:
        message:
          type: string
        statusCode:
          type: number     

You can reference those fragments in models like this:

  - 
    name: HttpStatusResponse
    contentType: "application/json"
    schema:
      type: object
      properties:
          serverResponse: 
            ${self:custom.commonModelSchemaFragments.HttpResponse}
          messageArray: 
            ${self:custom.commonModelSchemaFragments.StringArrayFragment}

Marking attributes optional

You can accomplish this by marking attributes as required. Simply provide a list of all attributes, except the ones you want to be optional. The json schema for that looks like this:

{
    "type": "object",
    "required": ["message"],
    "properties": {
        "optionalMessage": {
            "type": "string"
        },
        "message": {
            "type": "string"
        }
    }
}

which you would build by using yaml like this in your serverless file:

  -
    name: OptionalResponse
    contentType: "application/json"
    schema:
      type: object
      required: 
      - "message"
      properties:
        message:
          type: string
        optionalMessage:
          type: string

Note on request validation

Marking attributes required or optional only matters if request body validation is turned on:

Request body validation option in AWS console

I don't know of a way to turn on request validation using any special serverless syntax. It looks like you can do this in the resources section, but I haven't tried it. Source.

like image 155
Mike Patrick Avatar answered Oct 23 '22 18:10

Mike Patrick