httpserver

package
v0.0.0-...-e2a80a6 Latest Latest
Warning

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

Go to latest
Published: Nov 29, 2023 License: BSD-3-Clause Imports: 15 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultAccept = "*/*"

DefaultAccept 请求Header Accept的缺省值。

View Source
var DefaultHandlerFactory = HandlerFactory{
	ReadRequestFunc:   ReadRequest,
	Middleware:        RecoveryMiddleware,
	WriteResponseFunc: WriteResponse,
}

DefaultHandlerFactory 默认的Handler工厂。可修改,可覆盖。

View Source
var HandleRecovery = func(ctx context.Context, recovery interface{}) (overwriteRecovery interface{}) {
	return resterror.NewPanicError(recovery)
}

HandleRecovery RecoveryMiddleware 的recovery处理函数。 默认处理,可覆盖。

View Source
var RequestErrorWrapper = func(ctx context.Context, err error) error {
	return resterror.ErrorWithStatus(err, resterror.StatusInvalidArgument)
}

RequestErrorWrapper 请求处理错误包装。可以用来包装或覆盖请求错误。

View Source
var ValidateErrorWrapper = func(ctx context.Context, err error) error {
	return resterror.ErrorWithStatus(err, resterror.StatusInvalidArgument)
}

ValidateErrorWrapper 请求校验错误包装。可以用来包装或覆盖请求错误。

Functions

func HTTPStatusCode

func HTTPStatusCode(err error) int

HTTPStatus err对应的HTTP状态文本和状态码。 如果err为nil,返回200; 如果err实现了HTTPStatusError接口,返回HTTPStatus()的结果; 否则返回500。

func NewContextWithRequest

func NewContextWithRequest(ctx context.Context, r *http.Request) context.Context

NewContextWithRequest 将*http.Request保存到上下文。

func NewGenericsHandler

func NewGenericsHandler[REQUEST, RESPONSE any](f func(ctx context.Context, request *REQUEST) (response *RESPONSE, err error)) http.HandlerFunc

NewGenericsHandler 基于DefaultHandlerFactory和范型,创建一个http.Handler。

func NewHandler

func NewHandler(handling Handling) http.HandlerFunc

NewHandler 基于DefaultHandlerFactory创建一个http.Handler。

Example
type Request struct {
	Greeting string `schema:"greeting" validate:"required"`
}
type Response struct {
	Echo string `json:"echo"`
}

f := func(ctx context.Context, req *Request) (resp *Response, err error) {
	return &Response{
		Echo: req.Greeting,
	}, nil
}
var handler http.HandlerFunc = NewGenericsHandler(f)

s := httptest.NewServer(handler)
defer s.Close()

client := s.Client()
resp, err := client.Get(s.URL + "/echo?greeting=hello")
if err != nil {
	fmt.Println(err)
	return
}
if resp.StatusCode != http.StatusOK {
	fmt.Printf("status code: %d", resp.StatusCode)
	return
}

data, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
	fmt.Println(err)
	return
}

fmt.Println(string(data))
Output:
{"echo":"hello"}
Example (WithMiddleware)
type Request struct {
	Greeting string `schema:"greeting" validate:"required"`
}
type Response struct {
	Echo string `json:"echo"`
}

middleware := ChainHandlerMiddlewares(func(next HandleFunc) HandleFunc {
	return func(ctx context.Context, request interface{}) (response interface{}, err error) {
		r := RequestFromContext(ctx)
		fmt.Println(r.RequestURI)

		response, err = next(ctx, request)
		if err != nil {
			return nil, err
		}
		return struct {
			Data interface{} `json:"data"`
		}{
			Data: response,
		}, nil
	}
}, RecoveryMiddleware)

factory := DefaultHandlerFactory
factory.Middleware = middleware
f := func(ctx context.Context, req *Request) (resp *Response, err error) {
	return &Response{
		Echo: req.Greeting,
	}, nil
}
var handler http.HandlerFunc = factory.NewHandler(GenericsHandling[Request, Response](f))

s := httptest.NewServer(handler)
defer s.Close()

client := s.Client()
resp, err := client.Get(s.URL + "/echo?greeting=hello")
if err != nil {
	fmt.Println(err)
	return
}
if resp.StatusCode != http.StatusOK {
	fmt.Printf("status code: %d", resp.StatusCode)
	return
}

data, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
	fmt.Println(err)
	return
}

fmt.Println(string(data))
Output:
/echo?greeting=hello
{"data":{"echo":"hello"}}

func ReadRequest

func ReadRequest(ctx context.Context, dest interface{}, r *http.Request) error

ReadRequest 解析请求到对象。 支持GET的查询参数、POST/PUT/PATCH的Content-Type为application/json、application/x-www-form-urlencoded、application/x-protobuf的请求实体。 解析GET查询参数和application/x-www-form-urlencoded实体,需要dest对象字段带schema标签。

func ReadValidateRequest

func ReadValidateRequest(ctx context.Context, dest interface{}, r *http.Request) error

ReadValidateRequest 解析请求到对象。 会用github.com/go-playground/validator校验对象字段值。

func RequestFromContext

func RequestFromContext(ctx context.Context) *http.Request

RequestFromContext 从上下文中取得*http.Request对象。

func WriteResponse

func WriteResponse(ctx context.Context, w http.ResponseWriter, r *http.Request, response interface{}, err error) error

WriteResponse 将响应体写出。 response将被转为响应实体。 响应Content-Type根据请求的Accept推导。 如果err非nil,尝试转为HTTPStatusError接口,获取错误码。

Types

type GenericsHandling

type GenericsHandling[REQUEST, RESPONSE any] func(ctx context.Context, request *REQUEST) (response *RESPONSE, err error)

GenericsHandling 基于范型,将一个处理逻辑函数,转为Handling接口实现。

func (GenericsHandling[REQUEST, RESPONSE]) Handle

func (handling GenericsHandling[REQUEST, RESPONSE]) Handle(ctx context.Context, req interface{}) (resp interface{}, err error)

Handle 处理请求,返回响应。实现Handling接口。

func (GenericsHandling[REQUEST, RESPONSE]) NewRequest

func (handling GenericsHandling[REQUEST, RESPONSE]) NewRequest() interface{}

NewRequest 创建请求对象,返回请求对象的地址/指针。实现Handling接口。

type HTTPStatusError

type HTTPStatusError interface {
	error
	HTTPStatusCode() int
}

HTTPStatusError 提供Http状态码的错误接口。

type HandleFunc

type HandleFunc func(ctx context.Context, request interface{}) (response interface{}, err error)

HandleFunc Handling的Handle方法的类型。

func RecoveryMiddleware

func RecoveryMiddleware(next HandleFunc) HandleFunc

RecoveryMiddleware 处理panic的中间件。recover()返回值将被转为error。

type HandlerFactory

type HandlerFactory struct {
	// ReadRequestFunc 读请求函数。默认是:ReadRequest。
	ReadRequestFunc ReadRequestFunc

	// Middleware 中间件。多个中间件可以用ChainHandlerMiddlewares串联起来。默认是:RecoveryMiddleware。
	Middleware HandlerMiddleware

	// WriteResponseFunc 写响应的函数的签名。默认是:WriteResponse。
	WriteResponseFunc WriteResponseFunc
}

HandlerFactory Handler工厂。

func (HandlerFactory) NewHandler

func (factory HandlerFactory) NewHandler(handling Handling) http.HandlerFunc

NewHandler 创建一个http.Handler。

type HandlerMiddleware

type HandlerMiddleware func(next HandleFunc) HandleFunc

HandlerMiddleware Handler中间件。

func ChainHandlerMiddlewares

func ChainHandlerMiddlewares(middlewares ...HandlerMiddleware) HandlerMiddleware

HandlerMiddlewareChain 中间件链。

type Handling

type Handling interface {
	// NewRequest 创建请求对象,返回请求对象的地址/指针。
	NewRequest() interface{}

	// Handle 处理请求,返回响应。
	Handle(ctx context.Context, request interface{}) (response interface{}, err error)
}

Handling 处理逻辑的接口。GenericsHandling实现了该接口。

type ReadRequestFunc

type ReadRequestFunc func(ctx context.Context, dest interface{}, r *http.Request) error

ReadRequestFunc 解析请求的函数的签名。

type Server

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

Server http.Server的包装。 支持收到SIGTERM、SIGINT信号时结束监听。 支持等待全部处理过程结束。

Example
type Request struct {
	Greeting string `schema:"greeting" validate:"required"`
}
type Response struct {
	Echo string `json:"echo"`
}

ctx := context.Background()

s := NewServer(ctx, &http.Server{
	Addr: "127.0.0.1:28080",
	Handler: http.HandlerFunc(NewHandler(GenericsHandling[Request, Response](func(ctx context.Context, req *Request) (*Response, error) {
		return &Response{
			Echo: req.Greeting,
		}, nil
	}))),
})
addr, err := s.Start(ctx) //  启动监听,开始服务。直至收到SIGTERM、SIGINT信号,或Stop被调用。
if err != nil {
	fmt.Println(err)
	return
}
fmt.Println("Listen running at:", addr)

resp, err := http.Get("http://" + addr + "/echo?greeting=Hello")
if err != nil {
	fmt.Println(err)
	return
}
if resp.StatusCode != http.StatusOK {
	fmt.Printf("status code: %d", resp.StatusCode)
	return
}
data, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
	fmt.Println(err)
	return
}
fmt.Println(string(data))

s.Stop(ctx) // 结束监听。实际环境应该是内部接收退出信号

<-s.ShutdownNotify()
fmt.Println("exiting")

err = s.Wait(ctx) // 等待处理完
if err != nil {
	fmt.Println(err)
	return
}

fmt.Println("exited")
Output:
Listen running at: 127.0.0.1:28080
{"echo":"Hello"}

exiting
exited

func NewServer

func NewServer(ctx context.Context, srv *http.Server) *Server

NewServer 创建一个新的服务。

func (*Server) ShutdownNotify

func (s *Server) ShutdownNotify() <-chan interface{}

ShutdownNotify 服务关闭通知。

func (*Server) Start

func (s *Server) Start(ctx context.Context) (listenAddr string, err error)

Start 开始服务。 服务直至收到SIGTERM、SIGINT信号,或Stop被调用。 开始后返回。

func (*Server) StartTLS

func (s *Server) StartTLS(ctx context.Context, certFile, keyFile string) (listenAddr string, err error)

StartTLS 开始TLS服务。开始后返回。

func (*Server) Stop

func (s *Server) Stop(ctx context.Context)

Stop 停止服务。

func (*Server) Wait

func (s *Server) Wait(ctx context.Context) error

Wait 等待服务内全部后台过程结束。如果等待超时,返回错误包含还未退出的过程信息。

type WriteResponseFunc

type WriteResponseFunc func(ctx context.Context, w http.ResponseWriter, r *http.Request, response interface{}, err error) error

WriteResponseFunc 输出响应的函数的签名。

Directories

Path Synopsis
Package mock_httpserver is a generated GoMock package.
Package mock_httpserver is a generated GoMock package.
cache_example command

Jump to

Keyboard shortcuts

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