srvhttp

package
v0.12.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2022 License: MIT Imports: 15 Imported by: 3

Documentation

Overview

Package srvhttp groups helpers for server side http use cases. Components in the Package srvhttp must stay align with net/http implementation, rather than third party vendors such as gin.

Example (Modules)
package main

import (
	"net/http"

	"github.com/DoNewsCode/core"
	"github.com/DoNewsCode/core/srvhttp"
	"github.com/gorilla/mux"
)

func main() {
	c := core.New()
	defer c.Shutdown()

	c.AddModule(srvhttp.DocsModule{})
	c.AddModule(srvhttp.HealthCheckModule{})
	c.AddModule(srvhttp.MetricsModule{})
	c.AddModule(srvhttp.DebugModule{})

	router := mux.NewRouter()
	modules := c.Modules()
	for i := range modules {
		if m, ok := modules[i].(core.HTTPProvider); ok {
			m.ProvideHTTP(router)
		}
	}
	http.ListenAndServe(":8080", router)
}
Output:

Index

Examples

Constants

This section is empty.

Variables

Trace is an alias of nethttp.Middleware. It is recommended to use the trace implementation in github.com/opentracing-contrib/go-stdlib. This alias serves as a pointer to it.

Functions

func MakeApacheLogMiddleware

func MakeApacheLogMiddleware(logger log.Logger) func(handler http.Handler) http.Handler

MakeApacheLogMiddleware creates a standard HTTP middleware responsible for access logging.

func Metrics added in v0.9.0

func Metrics(metrics *RequestDurationSeconds) func(handler http.Handler) http.Handler

Metrics is a middleware for standard library http package. It records the request duration in a histogram.

Types

type ApacheLogAdapter

type ApacheLogAdapter struct {
	log.Logger
}

ApacheLogAdapter logs HTTP requests in the Apache Common Log Format.

See http://httpd.apache.org/docs/2.2/logs.html#common

func (ApacheLogAdapter) Write

func (a ApacheLogAdapter) Write(p []byte) (n int, err error)

Write redirect the data stream to the underlying log.Logger

type DebugModule

type DebugModule struct{}

DebugModule defines a http provider for container.Container. It calls pprof underneath. For instance, `/debug/pprof/cmdline` invokes pprof.Cmdline

func (DebugModule) ProvideHTTP added in v0.2.0

func (d DebugModule) ProvideHTTP(router *mux.Router)

ProvideHTTP implements container.HTTPProvider

type DocsModule

type DocsModule struct{}

DocsModule defines a http provider for container.Container. It serves static files under `./docs`. `./docs` is supposed to contain doc serving engines such as Swagger, Docify or plain markdowns.

func (DocsModule) ProvideHTTP added in v0.2.0

func (d DocsModule) ProvideHTTP(router *mux.Router)

ProvideHTTP implements container.HTTPProvider

type Headerer

type Headerer interface {
	// Headers provides the header map that will be sent by http.ResponseWriter WriteHeader.
	Headers() http.Header
}

type HealthCheckModule

type HealthCheckModule struct{}

HealthCheckModule defines a http provider for container.Container. It uses github.com/heptiolabs/healthcheck underneath. It doesn't do much out of box other than providing liveness check at “/live“ and readiness check at “/ready“. End user should add health checking functionality by themself, e.g. probe if database connection pool has exhausted at readiness check.

func (HealthCheckModule) ProvideHTTP added in v0.2.0

func (h HealthCheckModule) ProvideHTTP(router *mux.Router)

ProvideHTTP implements container.HTTPProvider

type MetricsModule

type MetricsModule struct{}

MetricsModule exposes prometheus metrics to `/metrics`. This is the standard route for prometheus metrics scrappers.

func (MetricsModule) ProvideHTTP added in v0.2.0

func (m MetricsModule) ProvideHTTP(router *mux.Router)

ProvideHTTP implements container.HTTPProvider

type RequestDurationSeconds added in v0.9.0

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

RequestDurationSeconds is a wrapper around a histogram that measures the request latency. The RequestDurationSeconds exposes label setters such as module, service and route. If a label is set more than once, the one set last will take precedence.

func NewRequestDurationSeconds added in v0.11.0

func NewRequestDurationSeconds(histogram metrics.Histogram) *RequestDurationSeconds

NewRequestDurationSeconds returns a new RequestDurationSeconds. The default labels are set to "unknown".

func (*RequestDurationSeconds) Module added in v0.9.0

Module specifies the module label for RequestDurationSeconds.

func (*RequestDurationSeconds) Observe added in v0.9.0

func (r *RequestDurationSeconds) Observe(duration time.Duration)

Observe records the time taken to process the request.

func (*RequestDurationSeconds) Route added in v0.9.0

Route specifies the method label for RequestDurationSeconds.

func (*RequestDurationSeconds) Service added in v0.9.0

Service specifies the service label for RequestDurationSeconds.

func (*RequestDurationSeconds) Status added in v0.12.0

Status specifies the status label for RequestDurationSeconds.

type ResponseEncoder

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

ResponseEncoder encodes either a successful http response or errors to the JSON format, and pipe the serialized json data to the http.ResponseWriter.

It asserts the type of input in following order and figures out the matching encoder:

json.Marshaler: use encoding/json encoder.
proto.Message: use the jsonpb encoder
error: {"message": err.Error()}
by default: encoding/json encoder.

It also populates http status code and headers if necessary.

func NewResponseEncoder

func NewResponseEncoder(w http.ResponseWriter) *ResponseEncoder

NewResponseEncoder wraps the http.ResponseWriter and returns a reference to ResponseEncoder

func (*ResponseEncoder) Encode

func (s *ResponseEncoder) Encode(response interface{}, err error)

Encode serialize response and error to the corresponding json format and write then to the output buffer.

See ResponseEncoder for details.

func (*ResponseEncoder) EncodeError

func (s *ResponseEncoder) EncodeError(err error)

EncodeError encodes an Error. If the error is not a StatusCoder, the http.StatusInternalServerError will be used.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"

	"github.com/DoNewsCode/core/srvhttp"
	"github.com/DoNewsCode/core/unierr"
	"google.golang.org/grpc/codes"
)

func main() {
	handler := func(writer http.ResponseWriter, request *http.Request) {
		encoder := srvhttp.NewResponseEncoder(writer)
		encoder.EncodeError(unierr.New(codes.NotFound, "foo is missing"))
	}
	req := httptest.NewRequest("GET", "http://example.com/foo", nil)
	w := httptest.NewRecorder()
	handler(w, req)

	resp := w.Result()
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	fmt.Println(resp.StatusCode)
	fmt.Println(resp.Header.Get("Content-Type"))
	fmt.Println(string(body))

}
Output:

404
application/json; charset=utf-8
{"code":5,"message":"foo is missing"}

func (*ResponseEncoder) EncodeResponse

func (s *ResponseEncoder) EncodeResponse(response interface{})

EncodeResponse encodes an response value. If the response is not a StatusCoder, the http.StatusInternalServerError will be used.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"

	"github.com/DoNewsCode/core/srvhttp"
)

func main() {
	handler := func(writer http.ResponseWriter, request *http.Request) {
		encoder := srvhttp.NewResponseEncoder(writer)
		encoder.EncodeResponse(struct {
			Foo string `json:"foo"`
		}{
			Foo: "bar",
		})
	}
	req := httptest.NewRequest("GET", "http://example.com/foo", nil)
	w := httptest.NewRecorder()
	handler(w, req)

	resp := w.Result()
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	fmt.Println(resp.StatusCode)
	fmt.Println(resp.Header.Get("Content-Type"))
	fmt.Println(string(body))

}
Output:

200
application/json; charset=utf-8
{"foo":"bar"}

type StatusCoder

type StatusCoder interface {
	// StatusCode provides the status code for the http response.
	StatusCode() int
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL