Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Commit

Permalink
feat(#2): Add swagger docs endpoint (#5)
Browse files Browse the repository at this point in the history
* feat(#2): Add removal of x-properties from openapi

* feat: Add config endpoint
  • Loading branch information
Timo Reymann authored Jan 5, 2023
1 parent b92624c commit f66c691
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 9 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,15 @@ No modules.
| <a name="input_api_gateway_id"></a> [api\_gateway\_id](#input\_api\_gateway\_id) | ID of the HTTP API-Gateway | `string` | `null` | no |
| <a name="input_create_api_endpoints"></a> [create\_api\_endpoints](#input\_create\_api\_endpoints) | Set this to false to add the endpoints inside your OpenAPI definition or your own terraform code | `bool` | `true` | no |
| <a name="input_create_log_group"></a> [create\_log\_group](#input\_create\_log\_group) | Should a log group be created for the lambda | `string` | `true` | no |
| <a name="input_enable_config_endpoint"></a> [enable\_config\_endpoint](#input\_enable\_config\_endpoint) | Enable config endpoint serving json | `bool` | `true` | no |
| <a name="input_enable_swagger_ui_entrypoint"></a> [enable\_swagger\_ui\_entrypoint](#input\_enable\_swagger\_ui\_entrypoint) | Enable swagger ui top level page to redirect to the swagger ui path allowing you to share a flat link and be consistent with e.g. Spring Boot apps | `string` | `true` | no |
| <a name="input_kms_key_arn"></a> [kms\_key\_arn](#input\_kms\_key\_arn) | ARN of the KMS key to use | `string` | `null` | no |
| <a name="input_log_group_retention_in_days"></a> [log\_group\_retention\_in\_days](#input\_log\_group\_retention\_in\_days) | Amount of days to keep logs | `number` | `3` | no |
| <a name="input_openapi_definition_content"></a> [openapi\_definition\_content](#input\_openapi\_definition\_content) | Content of openapi definition | `string` | n/a | yes |
| <a name="input_openapi_definition_format"></a> [openapi\_definition\_format](#input\_openapi\_definition\_format) | Format of definition | `string` | `"yaml"` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | Prefix to append to all resource names created. If not specified the API-Gateway name is used as prefix | `string` | `null` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | Name of the stage, when is not $default, the stage is suffixed for the lambda serving to match the path | `string` | `"$default"` | no |
| <a name="input_swagger_config_endpoint_path"></a> [swagger\_config\_endpoint\_path](#input\_swagger\_config\_endpoint\_path) | Config endpoint to serve swagger json | `string` | `"/swagger-config"` | no |
| <a name="input_swagger_ui_entrypoint_path"></a> [swagger\_ui\_entrypoint\_path](#input\_swagger\_ui\_entrypoint\_path) | Entrypoint for swagger ui redirect | `string` | `"/swagger-ui.html"` | no |
| <a name="input_swagger_ui_path"></a> [swagger\_ui\_path](#input\_swagger\_ui\_path) | Base path for swagger ui | `string` | `"/swagger-ui"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to assign to resources created by the module | `map(string)` | `{}` | no |
Expand Down
8 changes: 7 additions & 1 deletion apigateway_http.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
locals {
# route keys
routes = merge(local.default_routes, local.entrypoint_route)
routes = merge(local.default_routes, local.entrypoint_route, local.config_route)
default_routes = {
resources = {
method = "GET"
Expand All @@ -17,6 +17,12 @@ locals {
path = var.swagger_ui_entrypoint_path
}
} : {}
config_route = var.enable_config_endpoint ? {
config = {
method = "GET",
path = var.swagger_config_endpoint_path
}
} : {}
}

resource "aws_apigatewayv2_route" "this" {
Expand Down
Binary file modified code/dist/lambda.zip
Binary file not shown.
13 changes: 12 additions & 1 deletion code/src/apispec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,15 @@ const apiSpecFileContent = require("internal-apigateway-swagger")(apiSpecFileNam
const apiSpecParer = apiSpecFileName.endsWith("json") ? JSON.parse : require('yamljs').parse
const apiSpecDocument = apiSpecParer(apiSpecFileContent)

module.exports = apiSpecDocument
const removeXProperties = (definition) => Object.keys(definition).forEach(key => {
const nestedProperty = definition[key];
if (key.startsWith("x-")) {
delete definition[key]
} else if (typeof nestedProperty === 'object') {
removeXProperties(nestedProperty);
}
})

removeXProperties(apiSpecDocument)

module.exports = apiSpecDocument
12 changes: 11 additions & 1 deletion code/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ const swaggerUI = require('swagger-ui-express')

const pathConfig = {
uiPath: process.env.SWAGGER_UI_PATH || "/swagger-ui",
config: {
enabled: process.env.SWAGGER_CONFIG_ENDPOINT_ENABLED || true,
path: process.env.SWAGGER_CONFIG_ENDPOINT_PATH || "/swagger-config",
},
entrypoint: {
enabled: process.env.SWAGGER_UI_ENTRYPOINT_ENABLED || true,
path: process.env.SWAGGER_UI_ENTRYPOINT || "/swagger-ui.html"
Expand All @@ -22,11 +26,17 @@ app.use(
})
)

// enable swagger config endpoint
if (pathConfig.config.enabled) {
app.get(pathConfig.config.path, (req, res) => {
res.json(apiSpecDocument)
})
}

// redirect request from entrypoint to nested swagger ui path
if (pathConfig.entrypoint.enabled) {
app.get(pathConfig.entrypoint.path, (req, res) => {
res.redirect(302, `${pathConfig.uiPath}`)
return res;
})
}

Expand Down
2 changes: 1 addition & 1 deletion code/test/__mocks__/internal-apigateway-swagger.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = (fileName) => ""
module.exports = (fileName) => '{"version": "1.0.0"}'
7 changes: 7 additions & 0 deletions code/test/routes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,11 @@ describe("assets", () => {
.get("/")
expect(res.statusCode).toBe(404)
})

it("should returnjson for config", async () => {
const res = await request(app)
.get("/swagger-config")
expect(res.statusCode).toBe(200)
expect(res.body.version).toBe("1.0.0")
})
})
10 changes: 6 additions & 4 deletions lambda.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ resource "aws_lambda_function" "this" {

environment {
variables = {
SWAGGER_UI_PATH = "${local.route_serve_prefix}${var.swagger_ui_path}"
SWAGGER_SPEC_FILE = local.openapi_definition_filename
SWAGGER_UI_ENTRYPOINT_ENABLED = var.enable_swagger_ui_entrypoint
SWAGGER_UI_ENTRYPOINT = "${local.route_serve_prefix}${var.swagger_ui_entrypoint_path}"
SWAGGER_UI_PATH = "${local.route_serve_prefix}${var.swagger_ui_path}"
SWAGGER_SPEC_FILE = local.openapi_definition_filename
SWAGGER_UI_ENTRYPOINT_ENABLED = var.enable_swagger_ui_entrypoint
SWAGGER_UI_ENTRYPOINT = "${local.route_serve_prefix}${var.swagger_ui_entrypoint_path}"
SWAGGER_CONFIG_ENDPOINT_ENABLED = var.enable_config_endpoint
SWAGGER_CONFIG_ENDPOINT_PATH = "${local.route_serve_prefix}${var.swagger_config_endpoint_path}"
}
}

Expand Down
3 changes: 2 additions & 1 deletion tests/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func doHttpTestCall(t *testing.T, invoke_url string, status int, headers map[string]string) {
http_helper.HTTPDoWithRetry(t, "GET", invoke_url, []byte{}, headers, status, 10, 10*time.Second, &tls.Config{})
http_helper.HTTPDoWithRetry(t, "GET", invoke_url, []byte{}, headers, status, 3, 5*time.Second, &tls.Config{})
}

func testSwaggerEndpoints(t *testing.T, terraformOptions *terraform.Options, prefix string) {
Expand All @@ -19,4 +19,5 @@ func testSwaggerEndpoints(t *testing.T, terraformOptions *terraform.Options, pre
doHttpTestCall(t, base_url, 200, map[string]string{})
doHttpTestCall(t, base_url+"/swagger-ui.html", 200, map[string]string{})
doHttpTestCall(t, base_url+"/swagger-ui.css", 200, map[string]string{})
doHttpTestCall(t, invoke_url+prefix+"/swagger-config", 200, map[string]string{})
}
12 changes: 12 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ variable "stage" {
default = "$default"
}

variable "enable_config_endpoint" {
description = "Enable config endpoint serving json"
type = bool
default = true
}

variable "swagger_config_endpoint_path" {
description = "Config endpoint to serve swagger json"
type = string
default = "/swagger-config"
}

variable "enable_swagger_ui_entrypoint" {
description = "Enable swagger ui top level page to redirect to the swagger ui path allowing you to share a flat link and be consistent with e.g. Spring Boot apps"
type = string
Expand Down

0 comments on commit f66c691

Please sign in to comment.