Composable OpenAPI Specification (aka Swagger)

Overview

CI codecov Go Reference

compoas

Library for building, composing and serving OpenAPI Specification (aka Swagger).

Features

This lib provides:

  • golang structs which reflect OpenAPI Specification (check "Limitations" below),
  • embedded Swagger UI (through go:embed) and http.Handler for serving it,
  • functions for merging OpenAPI Specifications and dumping them into a file

Limitations

  • included golang structs not cover entire OpenAPI Specification
  • Swagger UI cannot be customized (only setting specification URL is possible)

Installation

go get github.com/graaphscom/compoas

Example code

Usage

Let's assume we're building a simple e-commerce app (same as in dbmigrat). This app is split into three modules. For now, each module exposes one REST API endpoint:

  • auth (provides an endpoint for signing up)
  • billing (provides an endpoint for fetching orders list - only for authenticated users)
  • inventory (provides an endpoint for fetching a single product)

At the end of this mini-tutorial we will have documentation for each separate module and one merged doc:

That's how our project's directory layout looks like:

|-- ecommerceapp
|   |-- auth
|   |   `-- openapi.go
|   |-- billing
|   |   `-- openapi.go
|   |-- cmd
|   |   |-- dump_openapi
|   |   |   `-- main.go
|   |   `-- start_http_server
|   |       |-- main.go
|   |       `-- openapi // this dir contains dumped specs
|   |           |-- auth.json
|   |           |-- billing.json
|   |           |-- inventory.json
|   |           `-- merged.json
|   `-- inventory
|       `-- openapi.go

At first, let's define OpenAPI Specification for each module. To save space in this README, I'm pasting spec only for the billing module.

billing/openapi.go:

package billing

import (
	"github.com/graaphscom/compoas"
	"github.com/graaphscom/compoas/internal/docs/ecommerceapp/auth"
	"github.com/graaphscom/compoas/internal/docs/ecommerceapp/inventory"
)

var Openapi = compoas.OAS{
	Openapi: "3.0.0",
	Info: compoas.Info{
		Title:   "Billing API",
		Version: "1.0.0",
	},
	Components: &compoas.Components{
		Schemas: map[string]compoas.Schema{
			"Order": {Type: "object", Properties: map[string]compoas.Schema{
				"id":    {Type: "integer"},
				"buyer": {Ref: "#/components/schemas/User-Read"},
				"items": {Type: "array", Items: &compoas.Schema{Ref: "#/components/schemas/Product"}},
			}},
			"User-Read": auth.Openapi.Components.Schemas["User-Read"],
			"Product":   inventory.Openapi.Components.Schemas["Product"],
		},
		SecuritySchemes: auth.Openapi.Components.SecuritySchemes,
	},
	Paths: map[string]compoas.PathItem{
		"/billing/orders": {
			Get: &compoas.Operation{
				Tags: []string{"Billing"},
				Responses: map[string]compoas.Response{
					"200": {Content: map[string]compoas.MediaType{
						"application/json": {Schema: &compoas.Schema{
							Type:  "array",
							Items: &compoas.Schema{Ref: "#/components/schemas/Order"},
						}},
					}},
				},
				Security: []compoas.SecurityRequirement{{"bearerAuth": {}}},
			},
		},
	},
}

inventory/openapi.go: check here

auth/openapi.go: check here

Now it's time to build a command for starting an HTTP server which will be exposing:

  • OpenAPI Specifications as JSON files
  • Swagger UI

Let's begin creating cmd/start_http_server/main.go file:

package main

import (
	"embed"
	"github.com/graaphscom/compoas"
	"log"
	"net/http"
)

//go:embed openapi
var dumpedSpecs embed.FS

func main() {
	oasHandler, err := compoas.UIHandler(
		compoas.SwaggerUIBundleConfig{Urls: []compoas.SwaggerUIBundleUrl{
			{Url: "/openapi/merged.json", Name: "All"},
			{Url: "/openapi/auth.json", Name: "Auth"},
			{Url: "/openapi/billing.json", Name: "Billing"},
			{Url: "/openapi/inventory.json", Name: "Inventory"},
		}},
		"/swagger-ui",
		log.Fatalln,
	)
	if err != nil {
		log.Fatalln(err)
	}

Above code configures handler for serving Swagger UI.

The first argument to the compoas.UIHandler defines URLs where specifications are available.

We want to have Swagger UI under route http://localhost:8080/swagger-ui. For that reason, the second argument to the compoas.UIHandler is /swagger-ui. If Swagger UI should be directly under http://localhost:8080 we would provide / as the second argument.

Now create a handler for static JSON specifications, configure routes and start listening:

package main

import (
	"embed"
	"github.com/graaphscom/compoas"
	"log"
	"net/http"
)

//go:embed openapi
var dumpedSpecs embed.FS

func main() {
	oasHandler, err := compoas.UIHandler(
		compoas.SwaggerUIBundleConfig{Urls: []compoas.SwaggerUIBundleUrl{
			{Url: "/openapi/merged.json", Name: "All"},
			{Url: "/openapi/auth.json", Name: "Auth"},
			{Url: "/openapi/billing.json", Name: "Billing"},
			{Url: "/openapi/inventory.json", Name: "Inventory"},
		}},
		"/swagger-ui",
		log.Fatalln,
	)
	if err != nil {
		log.Fatalln(err)
	}

+ 	mux := http.NewServeMux()
+ 	mux.Handle("/swagger-ui/", oasHandler)
+ 	mux.Handle("/openapi/", http.FileServer(http.FS(dumpedSpecs)))
+ 
+ 	log.Fatalln(http.ListenAndServe(":8080", mux))
+ }

As a final step, we need to prepare command for dumping specifications into JSON files. Let's start creating cmd/dump_openapi/main.go file:

package main

import (
	"github.com/graaphscom/compoas"
	"github.com/graaphscom/compoas/internal/docs/ecommerceapp/auth"
	"github.com/graaphscom/compoas/internal/docs/ecommerceapp/billing"
	"github.com/graaphscom/compoas/internal/docs/ecommerceapp/inventory"
	"log"
	"path"
)

func main() {
	const dir = "cmd/start_http_server/openapi"

	err := auth.Openapi.Dump(true, path.Join(dir, "auth.json"))
	err = billing.Openapi.Dump(true, path.Join(dir, "billing.json"))
	err = inventory.Openapi.Dump(true, path.Join(dir, "inventory.json"))

In the code above we're dumping each module's pretty-printed specification. To dump merged specifications we need to create a new empty specification, the remaining specifications will be merged into it:

package main

import (
	"github.com/graaphscom/compoas"
	"github.com/graaphscom/compoas/internal/docs/ecommerceapp/auth"
	"github.com/graaphscom/compoas/internal/docs/ecommerceapp/billing"
	"github.com/graaphscom/compoas/internal/docs/ecommerceapp/inventory"
	"log"
	"path"
)

func main() {
	const dir = "cmd/start_http_server/openapi"

	err := auth.Openapi.Dump(true, path.Join(dir, "auth.json"))
	err = billing.Openapi.Dump(true, path.Join(dir, "billing.json"))
	err = inventory.Openapi.Dump(true, path.Join(dir, "inventory.json"))

+ 	rootOpenapi := compoas.OAS{
+ 		Openapi: "3.0.0",
+ 		Info: compoas.Info{
+ 			Title:   "e-commerce app",
+ 			Version: "1.0.0",
+ 		},
+ 		Components: &compoas.Components{
+ 			Schemas:         map[string]compoas.Schema{},
+ 			SecuritySchemes: map[string]compoas.SecurityScheme{},
+ 		},
+ 		Paths: map[string]compoas.PathItem{},
+ 	}
+ 	err = rootOpenapi.Merge(auth.Openapi).
+ 		Merge(billing.Openapi).
+ 		Merge(inventory.Openapi).
+ 		Dump(true, path.Join(dir, "merged.json"))
+ 
+ 	if err != nil {
+ 		log.Fatalln(err)
+ 	}
+ }

It's time to start our HTTP server:

  1. make sure that directory cmd/start_http_server/openapi exists
  2. dump specifications - run go run cmd/dump_openapi/main.go
  3. start server - run go run cmd/start_http_server/main.go
  4. visit http://localhost:8080/swagger-ui in your web browser
Owner
Graaphs
Graaphs
Go types and validation for OpenAPI Specification 3.1

openapi Package openapi is a set of Go types for OpenAPI Specification 3.1. The primary purpose of the package is to assist in generation of OpenAPI d

Chance 4 May 4, 2022
Swagger-go-chi - Generate a go-chi server from swagger

swagger-go-chi Install go install github.com/cugu/[email protected] Run swagge

Jonas Plum 5 Mar 28, 2022
UPBit Auto Trading with OpenAPI Golang Module

Go-Bit! UPBit Auto Trading System with OpenAPI 이 레포지토리는 upbit를 위한 자동매매 프로그램을 개발하기 위해 제공하는 go module입니다. Features 구현 작업 진행상황 Sample Code Template shiel

Seongmin Kim 12 Jun 27, 2022
OpenAPI Client and Server Code Generator

This package contains a set of utilities for generating Go boilerplate code for services based on OpenAPI 3.0 API definitions

Discord Gophers 37 Jun 25, 2022
Entgo openapi example for go

entgo-openapi-example Example app created with ent entgen swagger-editor See https://entgo.io/blog/2021/09/10/openapi-generator/ License MIT Author Ya

mattn 7 Nov 27, 2021
This project extends the go-chi router to support OpenAPI 3, bringing to you a simple interface to build a router conforming your API contract.

Go OpenAPI This project extends the go-chi router to support OpenAPI 3, bringing to you a simple interface to build a router conforming your API contr

Tiago Angelo 2 Mar 27, 2022
Conversion from OpenAPI definitions to krakend configuration.

Description Basic conversion from OpenAPI specification to Krakend config. This is extendable with custom OpenAPI attributes and more support for both

Hamza Oral 9 Jun 14, 2022
Generates Golang client and server based on OpenAPI2 (swagger) definitions

ExperienceOne Golang APIKit ExperienceOne Golang APIKit Overview Requirements Installation Usage Generate standard project structure Define the API wi

Experience One 139 May 31, 2022
CRUD API server of Clean Architecture with Go(Echo), Gorm, MySQL, Docker and Swagger

CRUD API Server of Clean Architecture Go(echo) gorm mysql docker swagger build docker-compose up -d --build API Postman and Fiddler is recommended to

null 303 May 30, 2021
sso, aka S.S.Octopus, aka octoboi, is a single sign-on solution for securing internal services

sso See our launch blog post for more information! Please take the SSO Community Survey to let us know how we're doing, and to help us plan our roadma

BuzzFeed 2.9k Jun 21, 2022
Openapi - OpenAPI 3.x parser. Written in Go

OpenAPI OpenAPI specification object model Features Easy to integrate. Installat

null 6 May 5, 2022
OpenAPI Terraform Provider that configures itself at runtime with the resources exposed by the service provider (defined in a swagger file)

Terraform Provider OpenAPI This terraform provider aims to minimise as much as possible the efforts needed from service providers to create and mainta

Daniel I. Khan Ramiro 207 Jun 26, 2022
A diff tool for OpenAPI Specification 3

OpenAPI Diff This is a diff tool for OpenAPI Spec 3. It can be used in two ways: Generate a diff report in YAML, Text/Markdown or HTML from the cmd-li

Tufin 95 Jun 26, 2022
OpenAPI specification and related artifacts for HashiCorp Nomad

Overview This repository contains the HashiCorp Nomad OpenAPI specification and related artifacts. The OpenAPI specification defines a machine-readabl

HashiCorp 37 Jun 24, 2022
Go types and validation for OpenAPI Specification 3.1

openapi Package openapi is a set of Go types for OpenAPI Specification 3.1. The primary purpose of the package is to assist in generation of OpenAPI d

Chance 4 May 4, 2022
Swagger + Gin = SwaGin, a web framework based on Gin and Swagger

Swagger + Gin = SwaGin Introduction SwaGin is a web framework based on Gin and Swagger, which wraps Gin and provides built-in swagger api docs and req

long2ice 50 Jun 30, 2022
Swagger + Gin = SwaGin, a web framework based on Gin and Swagger

Swagger + Gin = SwaGin Introduction SwaGin is a web framework based on Gin and Swagger, which wraps Gin and provides built-in swagger api docs and req

long2ice 49 Jun 24, 2022
Swagger-go-chi - Generate a go-chi server from swagger

swagger-go-chi Install go install github.com/cugu/[email protected] Run swagge

Jonas Plum 5 Mar 28, 2022
Package for controlling the Windows firewall (aka Windows Filtering Platform, WFP)

wf What This is a package for controlling the Windows Filtering Platform (WFP), also known as the Windows firewall. See its docs: https://godoc.org/in

inet.af 41 May 26, 2022
Lightweight HTTP mocking in Go (aka golang)

httpmock This library builds on Go's built-in httptest library, adding a more mockable interface that can be used easily with other mocking tools like

null 77 Jun 27, 2022
Simple attempt at making a program to Brute Force Gift codes for Roberts Space Industries AKA Star Citizen.

Roberts Space Industries: Gift Generator Simple attempt at making a program to Brute Force Gift codes for Roberts Space Industries AKA Star Citizen. I

SaturnsVoid 2 Nov 2, 2021
The project aims to provide the utility for Kunlun-Cluster aka KTS

Kunlun Tool Set Description This project aims to provide the utility for Kunlun-Cluster aka 'KTS' Including but not limited to backup/restore tools...

zettadb 1 Dec 4, 2021
gup aka Get All Urls parameters to create wordlists for brute forcing parameters.

Description GUP is a tool to create wrodlists from the urls. Purpose The purpose of this tool is to create wordlists for brute forcing parameters. Ins

Chan Nyein Wai 14 Feb 25, 2022
Just a playground with some interesting concepts like pipelines aka middleware, handleFuncs, request validations etc. Check it out.

Pipeline a.k.a middleware in Go Just a playground with some interesting concepts like pipelines aka middleware, handleFuncs, request validations etc.

null 0 Dec 9, 2021
Statefulset-scheduler (aka sfs-scheduler)

statefulset-scheduler (aka sfs-scheduler) Installation I already upload docker i

Onur Yartaşı 2 Dec 19, 2021
This is a golang C2 + Implant that communicates via Protocol Buffers (aka. protobufs).

Br4vo6ix DISCLAIMER: This tool is for educational, competition, and training purposes only. I am in no way responsible for any abuse of this tool This

RITSEC Redteam 5 May 15, 2022
Golang - Learning go aka Flow with the go

golang learning go aka Flow with the go! helpful links tour of go: https://go.de

James Issac 0 Feb 3, 2022
Composable, observable and performant config handling for Go for the distributed processing era

Konfig Composable, observable and performant config handling for Go. Written for larger distributed systems where you may have plenty of configuration

Lalamove 628 Jun 12, 2022
Structured, composable logging for Go

log15 Package log15 provides an opinionated, simple toolkit for best-practice logging in Go (golang) that is both human and machine readable. It is mo

Alan Shreve 1.1k Jun 24, 2022