A small application to demonstrate how an OpenAPI v3.0 API can be implemented in Go and deployed to AWS using the HTTP API.
Check out this medium post FIXME for more information.
- Modern
go
toolchain - I used go 1.14.6 oapi-codegen
- AWS SAM application management tool
- Basic utilities:
zip
for function upload to AWS,curl
andjq
for testing
Clone this repo somewhere on your filesystem.
git clone github.com/seanrmurphy/lambda-openapi3-test
- Generate the types and server-side stub code
cd api
go generate
This generates two files api-server.gen.go
and api-types.gen.go
which contain
the server code and the types defined in the OAS3 specification respectively.
- Build the application
This application supports 2 modes: one in which the application runs locally and
one in which the application runs in AWS. main.go
provides a boolean lambdaMode
which determines whether the resulting binary should be run locally or as a Lamdba
function. Set lambdaMode
to false
to build a binary which can offer the API
locally.
go build
This builds the application in the top level directory of the repo.
- Run the application locally (optional)
If the application was built with lambdaMode
set to false
, you can run the
binary directly
./lambda-openapi3-test
You can then run the curl
based tests in the tests
directory.
- Deploy the application to AWS
If the binary is compiled with lambdaMode
set to true, then it can be deployed
to AWS. Assuming your AWS credentials are configured and SAM is set up
cd deploy
./deploy.sh
This zips the executable and uploads it to AWS using the sam
tool and
associated configuration file (sam-deploy.toml
). On successful completion, it
prints the identifier for the Lambda function and the endpoint of the HTTP API.
- Run the tests
cd ../tests
export RESTAPI=<ENDPOINT OUTPUT FROM DEPLOYMENT PROCESS>
./tests.sh
The tests demonstrate both successful and unsuccessful calling of all of the endpoints defined in the API.
- Removing the API
The easiest way to remove the application is via the AWS CloudFormations dashboard.
As noted in the medium post, oapi-codegen does not perform validation of the body of requests. This should be evident from the test suite provided.
One way of dealing with that is to apply this pull request. This
makes a new capability available to the oapi-codegen tool, that of validating
the unmarshall of objects. It operates by creating an UnmarshalJSON()
function
for schemas which are used as input parameters. You can achieve the same by
copying the code below to the api-types.gen.go
file and rebuilding.
Now, if you run the API locally, the tests generate an error when and incorrect JSON object is supplied and there is similar behaviour when the function is uploaded to AWS.
func (t *InputObject) UnmarshalJSON(data []byte) error {
inner := struct {
Descriptor *string `json:"descriptor,omitempty"`
IntVal *int `json:"int_val,omitempty"`
String *string `json:"string,omitempty"`
}{}
err := json.Unmarshal(data, &inner)
if err != nil {
return err
}
if inner.Descriptor == nil {
return errors.New("descriptor is required")
}
if inner.IntVal == nil {
return errors.New("int_val is required")
}
if inner.String == nil {
return errors.New("string is required")
}
*t = InputObject{
Descriptor: *inner.Descriptor,
IntVal: *inner.IntVal,
String: *inner.String,
}
return nil
}