hrpc

package module
v2.0.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2017 License: MIT Imports: 2 Imported by: 12

README

hrpc

Build Status Coverage Status Go Report Card GoDoc

Convert RPC style function into http.Handler

Install

go get -u github.com/acoshift/hrpc

Support input types

  • context.Context
  • *http.Request
  • http.ResponseWriter
  • interface{}

Support output types

  • interface{}
  • error

Example

Create new hrpc Manager
m := hrpc.New(hrpc.Config{
  RequestDecoder: func(r *http.Request, dst interface{}) error {
    return json.NewDecoder(r.Body).Decode(dst)
  },
  ResponseEncoder: func(w http.ResponseWriter, r *http.Request, res interface{}) {
    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    json.NewEncoder(w).Encode(res)
  },
  ErrorEncoder: func(w http.ResponseWriter, r *http.Request, err error) {
    res := &struct {
      Error string `json:"error"`
    }{err.Error()}
    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    w.WriteHeader(http.StatusInternalServerError)
    json.NewEncoder(w).Encode(res)
  },
  Validate: true,
})
RPC style function
type UserRequest struct {
  ID int `json:"id"`
}

type UserResponse struct {
  ID int `json:"id"`
  Username string `json:"username"`
}

http.Handle("/user.get", m.Handler(func(ctx context.Context, req *UserRequest) (*UserResponse, error) {
  return &UserResponse{ID: 1, Username: "acoshift"}, nil
}))
gRPC service client (generated from .proto)
m.Handler(func(ctx context.Context, in *UserRequest, opts ...grpc.CallOption) (*UserResponse, error) {
  return nil, errors.New("not implemented")
})
Mixed types
m.Handler(func(r *http.Request) error {
  buf := &bytes.Buffer{}
  _, err := io.Copy(buf, r.Body)
  if err != nil {
    return err
  }
  fmt.Printf("upload data: %s\n", buf.String())
  return nil
})

m.Handler(func(w http.ResponseWriter, r *http.Request) {})

m.Handler(func(ctx context.Context, r *http.Request, w http.ResponseWriter) {})

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	RequestDecoder  func(*http.Request, interface{}) error
	ResponseEncoder func(http.ResponseWriter, *http.Request, interface{})
	ErrorEncoder    func(http.ResponseWriter, *http.Request, error)
	Validate        bool // set to true to validate request after decode using Validatable interface
}

Config is the hrpc config

type Manager

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

Manager type

Example
m := New(Config{
	RequestDecoder: func(r *http.Request, dst interface{}) error {
		return json.NewDecoder(r.Body).Decode(dst)
	},
	ResponseEncoder: func(w http.ResponseWriter, r *http.Request, res interface{}) {
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		json.NewEncoder(w).Encode(res)
	},
	ErrorEncoder: func(w http.ResponseWriter, r *http.Request, err error) {
		res := &struct {
			Error string `json:"error"`
		}{err.Error()}
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(res)
	},
	Validate: true,
})

http.Handle("/user.get", m.Handler(func(ctx context.Context, req *struct {
	ID string `json:"id"`
}) (map[string]string, error) {
	return map[string]string{
		"user_id":   req.ID,
		"user_name": "User " + req.ID,
	}, nil
}))
// $ curl -X POST -d '{"id":"123"}' http://localhost:8080/user.get
// {"user_id":"123","user_name":"User 123"}

http.Handle("/upload", m.Handler(func(r *http.Request) error {
	buf := &bytes.Buffer{}
	_, err := io.Copy(buf, r.Body)
	if err != nil {
		return err
	}
	fmt.Printf("upload data: %s\n", buf.String())
	return nil
}))
// $ echo "test data" | curl -X POST -d "@-" http://localhost:8080/upload
// upload data: test data

http.ListenAndServe(":8080", nil)
Output:

func New

func New(config Config) *Manager

New creates new manager

func (*Manager) Handler

func (m *Manager) Handler(f interface{}) http.Handler

Handler func, f must be a function which have at least 2 inputs and 2 outputs. first input must be a context. second input can be anything which will pass to RequestDecoder function. first output must be the result which will pass to success handler. second output must be an error interface which will pass to error handler if not nil.

type Validatable

type Validatable interface {
	Validate() error
}

Validatable interface

Jump to

Keyboard shortcuts

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