README

go-httpdoc Go Documentation Travis Codecov

go-httpdoc is a Golang package to generate API documentation from httptest test cases.

It provides a simple http middleware which records http requests and responses from tests and generates documentation automatically in markdown format. See Sample Documentation. It also provides a way to validate values are equal to what you expect with annotation (e.g., you can add a description for headers, params or response fields). If you write proper tests, it will generate usable documentation (namely, it forces you to write good tests).

Not only JSON request and response but it also supports protocol buffer. See Sample ProtoBuf Documentation).

See usage and example in GoDoc.

NOTE: This package is experimental and may make backward-incompatible changes.

Prerequisites

go-httpdoc requires Go 1.7 or later.

Install

Use go get:

$ go get -u go.mercari.io/go-httpdoc

Usage

All usage are described in GoDoc.

To generate documentation, set the following env var:

$ export HTTPDOC=1

Reference

The original idea came from r7kamura/autodoc (rack middleware).

For struct inspection in validator, it uses tenntenn/gpath package.

Documentation

Overview

Package httpdoc is a Golang package for generating API documentation from httptest test cases.

It provides a simple http middleware for recording various http requst & response values you use in your tests and automatically arranges and generates them as usable documentation in markdown format. It also provides a way to validate values are equal to what you expect with annotation (e.g., you can add a description for headers, params or response fields).

See example document output, https://github.com/mercari/go-httpdoc/blob/master/_example/doc/validate.md

Index

Constants

View Source
const (
	// EnvHTTPDoc is the environmental variable that determines if Generate func generates documentation
	// to the given file or not. By default, it does not generate. If this variable is not empty, then it does.
	EnvHTTPDoc = "HTTPDOC"
)

Variables

This section is empty.

Functions

func Record

func Record(next http.Handler, document *Document, opt *RecordOption) http.Handler

Record is a http middleware. It records all request & response values which the given http handler receives & response and save it in the given Document.

Types

type Data

type Data struct {
	// Name is header or params, field name.
	Name string

	// Value is actual value handler receives.
	Value interface{}

	// Description is description for this data. You can provide this via a validator.
	Description string
}

Data represents a request or response parameter value. Normally, you don't need to modify this. All fields are exported just for templating.

type Document

type Document struct {
	// Name is API documentation name.
	Name string

	// ExcludeHeaders is list of headers to exclude from documentation.
	// For example, you may do not need `Content-Length` header. This is applied all entries (endpoints).
	// If you want to exclude header only in specific endpoint, then use `RecordOption.ExcludeHeaders`.
	ExcludeHeaders []string

	// Entries stores all recorded results by Record middleware. Normally, you don't need to modify this.
	// This is exported just for templating.
	Entries []Entry
	// contains filtered or unexported fields
}

Document stores recorded results by Record middleware.

func (*Document) Generate

func (d *Document) Generate(path string) error

Generate writes documentation into the given file. Generation is skipped if EnvHTTPDoc is empty. If directory does not exist or any, it returns error.

type Entry

type Entry struct {
	// Description is description of endpoint.
	Description string

	// Method is HTTP method.
	Method string

	// Path is request path.
	Path string

	RequestParams  []Data
	RequestHeaders []Data
	RequestFields  []Data

	// RequestExample is request body example. If you use plain text for json for response body
	// it uses it here without modification. If you use protocol buffer format for your request body
	// it unmarshals it in the given struct and encodes it into json format.
	RequestExample string

	ResponseStatusCode int
	ResponseHeaders    []Data
	ResponseFields     []Data

	// ResponseExample is response body example. If you use plain text for json for response body
	// it uses it here without modification. If you use protocol buffer format for your response body
	// it unmarshals it in the given struct and encodes it into json format.
	ResponseExample string
}

Entry is recorded results by Record middleware. Normally, you don't need to modify this. All fields are exported just for templating.

type ProtoBufferOption

type ProtoBufferOption struct {
	// RequestUnmarshaler is used to unmarshal protocol buffer encoded request body.
	// This is used for generating human readable request example (json format).
	RequestUnmarshaler proto.Unmarshaler

	// ResponseUnmarshaler is used to unmarshal protocol buffer encoded response body.
	// This is used for generating human readable response example (json format).
	ResponseUnmarshaler proto.Unmarshaler
}

ProtoBufferOption is option for protocol buffer.

type RecordOption

type RecordOption struct {
	// Description is description of endpoint. This is used for Entry.Description.
	Description string

	// ExcludeHeaders is list of headers to exclude from documentation.
	// This is applied only one entry (endpoint). If you want to exclude header in all endpoints
	// use `Document.ExcludeHeaders`.
	ExcludeHeaders []string

	// WithValidate option, you can validate various http request & response parameter values.
	// It inspects values which handler receives and checks it's expected or not.
	// If not it asserts and fails the test. If ok, uses it for documentaion entry.
	//
	// Not only validate, you can add an annotation to each values (e.g., what does the header
	// means?) and it's used for documentation.
	//
	// See more usage in Validator methods.
	WithValidate func(*Validator)

	// WithProtoBuffer option is used for protocol buffer request & response.
	WithProtoBuffer *ProtoBufferOption
}

RecordOption is option for Record middleware.

type TestCase

type TestCase struct {
	Target      string
	Expected    interface{}
	Description string
	AssertFunc  assertFunc
}

TestCase is test case validator uses. Validator inspects and extract request & response value based on Target (e.g, when testing request params, target is parameter name. when testing response body, target is filed name) and asserts with Expected value.

TestCase can be used like table-driven way.

  validator.RequestParams(t, []httpdoc.TestCase{
      NewTestCase("token","12345","Request token"),
      NewTestCase("pretty","true","Pretty print response message"),
	 })

func NewTestCase

func NewTestCase(target string, expected interface{}, description string) TestCase

NewTestCase returns new TestCase.

type Validator

type Validator struct {
	// contains filtered or unexported fields
}

Validator takes test cases and checks whether recorded values are equal to the given expected values. If not, it fails in the given test context. If ok, it uses the result for documentation.

func (*Validator) RequestBody

func (v *Validator) RequestBody(t *testing.T, cases []TestCase, request interface{})

RequestBody validates request body's fileds are expected or not. The request body is unmarshaled to the given struct. To extract a filed to validate, this uses dot-seprated expression in TestCase.Target. For example, if you want to access `Email` value in the following struct use `Setting.Name` in Target.

type User struct {
    Setting Setting
}

type Setting struct {
    Email string
}

func (*Validator) RequestHeaders

func (v *Validator) RequestHeaders(t *testing.T, cases []TestCase)

RequestHeaders validates request headers are expected or not.

func (*Validator) RequestParams

func (v *Validator) RequestParams(t *testing.T, cases []TestCase)

RequestParams validated request params are expected or not.

func (*Validator) ResponseBody

func (v *Validator) ResponseBody(t *testing.T, cases []TestCase, response interface{})

ResponseBody validates response body's fields are expected or not. The response body is unmarshaled to the given struct. To extract a filed to validate, this uses dot-seprated expression in TestCase.Target. For example, if you want to access `Email` value in the following struct use `Setting.Name` in Target.

type User struct {
    Setting Setting
}

type Setting struct {
    Email string
}

func (*Validator) ResponseHeaders

func (v *Validator) ResponseHeaders(t *testing.T, cases []TestCase)

ResponseHeaders validates response headers are expected or not.

func (*Validator) ResponseStatusCode

func (v *Validator) ResponseStatusCode(t *testing.T, expected int)

ResponseStatusCode validates response status code is expected or not.

Directories

Path Synopsis
Package httpdoc is a generated protocol buffer package.
Package httpdoc is a generated protocol buffer package.