Moved to google.golang.org/genproto/googleapis/api/annotations
Fixes #52
This commit is contained in:
4
vendor/github.com/go-kit/kit/examples/profilesvc/README.md
generated
vendored
Normal file
4
vendor/github.com/go-kit/kit/examples/profilesvc/README.md
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# profilesvc
|
||||
|
||||
This example demonstrates how to use Go kit to implement a REST-y HTTP service.
|
||||
It leverages the excellent [gorilla mux package](https://github.com/gorilla/mux) for routing.
|
||||
120
vendor/github.com/go-kit/kit/examples/profilesvc/client/client.go
generated
vendored
Normal file
120
vendor/github.com/go-kit/kit/examples/profilesvc/client/client.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
// Package client provides a profilesvc client based on a predefined Consul
|
||||
// service name and relevant tags. Users must only provide the address of a
|
||||
// Consul server.
|
||||
package client
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
consulapi "github.com/hashicorp/consul/api"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
"github.com/go-kit/kit/examples/profilesvc"
|
||||
"github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/sd"
|
||||
"github.com/go-kit/kit/sd/consul"
|
||||
"github.com/go-kit/kit/sd/lb"
|
||||
)
|
||||
|
||||
// New returns a service that's load-balanced over instances of profilesvc found
|
||||
// in the provided Consul server. The mechanism of looking up profilesvc
|
||||
// instances in Consul is hard-coded into the client.
|
||||
func New(consulAddr string, logger log.Logger) (profilesvc.Service, error) {
|
||||
apiclient, err := consulapi.NewClient(&consulapi.Config{
|
||||
Address: consulAddr,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// As the implementer of profilesvc, we declare and enforce these
|
||||
// parameters for all of the profilesvc consumers.
|
||||
var (
|
||||
consulService = "profilesvc"
|
||||
consulTags = []string{"prod"}
|
||||
passingOnly = true
|
||||
retryMax = 3
|
||||
retryTimeout = 500 * time.Millisecond
|
||||
)
|
||||
|
||||
var (
|
||||
sdclient = consul.NewClient(apiclient)
|
||||
endpoints profilesvc.Endpoints
|
||||
)
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakePostProfileEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.PostProfileEndpoint = retry
|
||||
}
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakeGetProfileEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.GetProfileEndpoint = retry
|
||||
}
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakePutProfileEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.PutProfileEndpoint = retry
|
||||
}
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakePatchProfileEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.PatchProfileEndpoint = retry
|
||||
}
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakeDeleteProfileEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.DeleteProfileEndpoint = retry
|
||||
}
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakeGetAddressesEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.GetAddressesEndpoint = retry
|
||||
}
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakeGetAddressEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.GetAddressEndpoint = retry
|
||||
}
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakePostAddressEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.PostAddressEndpoint = retry
|
||||
}
|
||||
{
|
||||
factory := factoryFor(profilesvc.MakeDeleteAddressEndpoint)
|
||||
subscriber := consul.NewSubscriber(sdclient, factory, logger, consulService, consulTags, passingOnly)
|
||||
balancer := lb.NewRoundRobin(subscriber)
|
||||
retry := lb.Retry(retryMax, retryTimeout, balancer)
|
||||
endpoints.DeleteAddressEndpoint = retry
|
||||
}
|
||||
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func factoryFor(makeEndpoint func(profilesvc.Service) endpoint.Endpoint) sd.Factory {
|
||||
return func(instance string) (endpoint.Endpoint, io.Closer, error) {
|
||||
service, err := profilesvc.MakeClientEndpoints(instance)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return makeEndpoint(service), nil, nil
|
||||
}
|
||||
}
|
||||
52
vendor/github.com/go-kit/kit/examples/profilesvc/cmd/profilesvc/main.go
generated
vendored
Normal file
52
vendor/github.com/go-kit/kit/examples/profilesvc/cmd/profilesvc/main.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/go-kit/kit/examples/profilesvc"
|
||||
"github.com/go-kit/kit/log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
httpAddr = flag.String("http.addr", ":8080", "HTTP listen address")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
var logger log.Logger
|
||||
{
|
||||
logger = log.NewLogfmtLogger(os.Stderr)
|
||||
logger = log.With(logger, "ts", log.DefaultTimestampUTC)
|
||||
logger = log.With(logger, "caller", log.DefaultCaller)
|
||||
}
|
||||
|
||||
var s profilesvc.Service
|
||||
{
|
||||
s = profilesvc.NewInmemService()
|
||||
s = profilesvc.LoggingMiddleware(logger)(s)
|
||||
}
|
||||
|
||||
var h http.Handler
|
||||
{
|
||||
h = profilesvc.MakeHTTPHandler(s, log.With(logger, "component", "HTTP"))
|
||||
}
|
||||
|
||||
errs := make(chan error)
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
logger.Log("transport", "HTTP", "addr", *httpAddr)
|
||||
errs <- http.ListenAndServe(*httpAddr, h)
|
||||
}()
|
||||
|
||||
logger.Log("exit", <-errs)
|
||||
}
|
||||
387
vendor/github.com/go-kit/kit/examples/profilesvc/endpoints.go
generated
vendored
Normal file
387
vendor/github.com/go-kit/kit/examples/profilesvc/endpoints.go
generated
vendored
Normal file
@@ -0,0 +1,387 @@
|
||||
package profilesvc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
httptransport "github.com/go-kit/kit/transport/http"
|
||||
)
|
||||
|
||||
// Endpoints collects all of the endpoints that compose a profile service. It's
|
||||
// meant to be used as a helper struct, to collect all of the endpoints into a
|
||||
// single parameter.
|
||||
//
|
||||
// In a server, it's useful for functions that need to operate on a per-endpoint
|
||||
// basis. For example, you might pass an Endpoints to a function that produces
|
||||
// an http.Handler, with each method (endpoint) wired up to a specific path. (It
|
||||
// is probably a mistake in design to invoke the Service methods on the
|
||||
// Endpoints struct in a server.)
|
||||
//
|
||||
// In a client, it's useful to collect individually constructed endpoints into a
|
||||
// single type that implements the Service interface. For example, you might
|
||||
// construct individual endpoints using transport/http.NewClient, combine them
|
||||
// into an Endpoints, and return it to the caller as a Service.
|
||||
type Endpoints struct {
|
||||
PostProfileEndpoint endpoint.Endpoint
|
||||
GetProfileEndpoint endpoint.Endpoint
|
||||
PutProfileEndpoint endpoint.Endpoint
|
||||
PatchProfileEndpoint endpoint.Endpoint
|
||||
DeleteProfileEndpoint endpoint.Endpoint
|
||||
GetAddressesEndpoint endpoint.Endpoint
|
||||
GetAddressEndpoint endpoint.Endpoint
|
||||
PostAddressEndpoint endpoint.Endpoint
|
||||
DeleteAddressEndpoint endpoint.Endpoint
|
||||
}
|
||||
|
||||
// MakeServerEndpoints returns an Endpoints struct where each endpoint invokes
|
||||
// the corresponding method on the provided service. Useful in a profilesvc
|
||||
// server.
|
||||
func MakeServerEndpoints(s Service) Endpoints {
|
||||
return Endpoints{
|
||||
PostProfileEndpoint: MakePostProfileEndpoint(s),
|
||||
GetProfileEndpoint: MakeGetProfileEndpoint(s),
|
||||
PutProfileEndpoint: MakePutProfileEndpoint(s),
|
||||
PatchProfileEndpoint: MakePatchProfileEndpoint(s),
|
||||
DeleteProfileEndpoint: MakeDeleteProfileEndpoint(s),
|
||||
GetAddressesEndpoint: MakeGetAddressesEndpoint(s),
|
||||
GetAddressEndpoint: MakeGetAddressEndpoint(s),
|
||||
PostAddressEndpoint: MakePostAddressEndpoint(s),
|
||||
DeleteAddressEndpoint: MakeDeleteAddressEndpoint(s),
|
||||
}
|
||||
}
|
||||
|
||||
// MakeClientEndpoints returns an Endpoints struct where each endpoint invokes
|
||||
// the corresponding method on the remote instance, via a transport/http.Client.
|
||||
// Useful in a profilesvc client.
|
||||
func MakeClientEndpoints(instance string) (Endpoints, error) {
|
||||
if !strings.HasPrefix(instance, "http") {
|
||||
instance = "http://" + instance
|
||||
}
|
||||
tgt, err := url.Parse(instance)
|
||||
if err != nil {
|
||||
return Endpoints{}, err
|
||||
}
|
||||
tgt.Path = ""
|
||||
|
||||
options := []httptransport.ClientOption{}
|
||||
|
||||
// Note that the request encoders need to modify the request URL, changing
|
||||
// the path and method. That's fine: we simply need to provide specific
|
||||
// encoders for each endpoint.
|
||||
|
||||
return Endpoints{
|
||||
PostProfileEndpoint: httptransport.NewClient("POST", tgt, encodePostProfileRequest, decodePostProfileResponse, options...).Endpoint(),
|
||||
GetProfileEndpoint: httptransport.NewClient("GET", tgt, encodeGetProfileRequest, decodeGetProfileResponse, options...).Endpoint(),
|
||||
PutProfileEndpoint: httptransport.NewClient("PUT", tgt, encodePutProfileRequest, decodePutProfileResponse, options...).Endpoint(),
|
||||
PatchProfileEndpoint: httptransport.NewClient("PATCH", tgt, encodePatchProfileRequest, decodePatchProfileResponse, options...).Endpoint(),
|
||||
DeleteProfileEndpoint: httptransport.NewClient("DELETE", tgt, encodeDeleteProfileRequest, decodeDeleteProfileResponse, options...).Endpoint(),
|
||||
GetAddressesEndpoint: httptransport.NewClient("GET", tgt, encodeGetAddressesRequest, decodeGetAddressesResponse, options...).Endpoint(),
|
||||
GetAddressEndpoint: httptransport.NewClient("GET", tgt, encodeGetAddressRequest, decodeGetAddressResponse, options...).Endpoint(),
|
||||
PostAddressEndpoint: httptransport.NewClient("POST", tgt, encodePostAddressRequest, decodePostAddressResponse, options...).Endpoint(),
|
||||
DeleteAddressEndpoint: httptransport.NewClient("DELETE", tgt, encodeDeleteAddressRequest, decodeDeleteAddressResponse, options...).Endpoint(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PostProfile implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) PostProfile(ctx context.Context, p Profile) error {
|
||||
request := postProfileRequest{Profile: p}
|
||||
response, err := e.PostProfileEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := response.(postProfileResponse)
|
||||
return resp.Err
|
||||
}
|
||||
|
||||
// GetProfile implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) GetProfile(ctx context.Context, id string) (Profile, error) {
|
||||
request := getProfileRequest{ID: id}
|
||||
response, err := e.GetProfileEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return Profile{}, err
|
||||
}
|
||||
resp := response.(getProfileResponse)
|
||||
return resp.Profile, resp.Err
|
||||
}
|
||||
|
||||
// PutProfile implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) PutProfile(ctx context.Context, id string, p Profile) error {
|
||||
request := putProfileRequest{ID: id, Profile: p}
|
||||
response, err := e.PutProfileEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := response.(putProfileResponse)
|
||||
return resp.Err
|
||||
}
|
||||
|
||||
// PatchProfile implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) PatchProfile(ctx context.Context, id string, p Profile) error {
|
||||
request := patchProfileRequest{ID: id, Profile: p}
|
||||
response, err := e.PatchProfileEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := response.(patchProfileResponse)
|
||||
return resp.Err
|
||||
}
|
||||
|
||||
// DeleteProfile implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) DeleteProfile(ctx context.Context, id string) error {
|
||||
request := deleteProfileRequest{ID: id}
|
||||
response, err := e.DeleteProfileEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := response.(deleteProfileResponse)
|
||||
return resp.Err
|
||||
}
|
||||
|
||||
// GetAddresses implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) GetAddresses(ctx context.Context, profileID string) ([]Address, error) {
|
||||
request := getAddressesRequest{ProfileID: profileID}
|
||||
response, err := e.GetAddressesEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := response.(getAddressesResponse)
|
||||
return resp.Addresses, resp.Err
|
||||
}
|
||||
|
||||
// GetAddress implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) GetAddress(ctx context.Context, profileID string, addressID string) (Address, error) {
|
||||
request := getAddressRequest{ProfileID: profileID, AddressID: addressID}
|
||||
response, err := e.GetAddressEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return Address{}, err
|
||||
}
|
||||
resp := response.(getAddressResponse)
|
||||
return resp.Address, resp.Err
|
||||
}
|
||||
|
||||
// PostAddress implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) PostAddress(ctx context.Context, profileID string, a Address) error {
|
||||
request := postAddressRequest{ProfileID: profileID, Address: a}
|
||||
response, err := e.PostAddressEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := response.(postAddressResponse)
|
||||
return resp.Err
|
||||
}
|
||||
|
||||
// DeleteAddress implements Service. Primarily useful in a client.
|
||||
func (e Endpoints) DeleteAddress(ctx context.Context, profileID string, addressID string) error {
|
||||
request := deleteAddressRequest{ProfileID: profileID, AddressID: addressID}
|
||||
response, err := e.DeleteAddressEndpoint(ctx, request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := response.(deleteAddressResponse)
|
||||
return resp.Err
|
||||
}
|
||||
|
||||
// MakePostProfileEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakePostProfileEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(postProfileRequest)
|
||||
e := s.PostProfile(ctx, req.Profile)
|
||||
return postProfileResponse{Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakeGetProfileEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakeGetProfileEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(getProfileRequest)
|
||||
p, e := s.GetProfile(ctx, req.ID)
|
||||
return getProfileResponse{Profile: p, Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakePutProfileEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakePutProfileEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(putProfileRequest)
|
||||
e := s.PutProfile(ctx, req.ID, req.Profile)
|
||||
return putProfileResponse{Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakePatchProfileEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakePatchProfileEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(patchProfileRequest)
|
||||
e := s.PatchProfile(ctx, req.ID, req.Profile)
|
||||
return patchProfileResponse{Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakeDeleteProfileEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakeDeleteProfileEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(deleteProfileRequest)
|
||||
e := s.DeleteProfile(ctx, req.ID)
|
||||
return deleteProfileResponse{Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakeGetAddressesEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakeGetAddressesEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(getAddressesRequest)
|
||||
a, e := s.GetAddresses(ctx, req.ProfileID)
|
||||
return getAddressesResponse{Addresses: a, Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakeGetAddressEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakeGetAddressEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(getAddressRequest)
|
||||
a, e := s.GetAddress(ctx, req.ProfileID, req.AddressID)
|
||||
return getAddressResponse{Address: a, Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakePostAddressEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakePostAddressEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(postAddressRequest)
|
||||
e := s.PostAddress(ctx, req.ProfileID, req.Address)
|
||||
return postAddressResponse{Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakeDeleteAddressEndpoint returns an endpoint via the passed service.
|
||||
// Primarily useful in a server.
|
||||
func MakeDeleteAddressEndpoint(s Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
req := request.(deleteAddressRequest)
|
||||
e := s.DeleteAddress(ctx, req.ProfileID, req.AddressID)
|
||||
return deleteAddressResponse{Err: e}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// We have two options to return errors from the business logic.
|
||||
//
|
||||
// We could return the error via the endpoint itself. That makes certain things
|
||||
// a little bit easier, like providing non-200 HTTP responses to the client. But
|
||||
// Go kit assumes that endpoint errors are (or may be treated as)
|
||||
// transport-domain errors. For example, an endpoint error will count against a
|
||||
// circuit breaker error count.
|
||||
//
|
||||
// Therefore, it's often better to return service (business logic) errors in the
|
||||
// response object. This means we have to do a bit more work in the HTTP
|
||||
// response encoder to detect e.g. a not-found error and provide a proper HTTP
|
||||
// status code. That work is done with the errorer interface, in transport.go.
|
||||
// Response types that may contain business-logic errors implement that
|
||||
// interface.
|
||||
|
||||
type postProfileRequest struct {
|
||||
Profile Profile
|
||||
}
|
||||
|
||||
type postProfileResponse struct {
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r postProfileResponse) error() error { return r.Err }
|
||||
|
||||
type getProfileRequest struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
type getProfileResponse struct {
|
||||
Profile Profile `json:"profile,omitempty"`
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r getProfileResponse) error() error { return r.Err }
|
||||
|
||||
type putProfileRequest struct {
|
||||
ID string
|
||||
Profile Profile
|
||||
}
|
||||
|
||||
type putProfileResponse struct {
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r putProfileResponse) error() error { return nil }
|
||||
|
||||
type patchProfileRequest struct {
|
||||
ID string
|
||||
Profile Profile
|
||||
}
|
||||
|
||||
type patchProfileResponse struct {
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r patchProfileResponse) error() error { return r.Err }
|
||||
|
||||
type deleteProfileRequest struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
type deleteProfileResponse struct {
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r deleteProfileResponse) error() error { return r.Err }
|
||||
|
||||
type getAddressesRequest struct {
|
||||
ProfileID string
|
||||
}
|
||||
|
||||
type getAddressesResponse struct {
|
||||
Addresses []Address `json:"addresses,omitempty"`
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r getAddressesResponse) error() error { return r.Err }
|
||||
|
||||
type getAddressRequest struct {
|
||||
ProfileID string
|
||||
AddressID string
|
||||
}
|
||||
|
||||
type getAddressResponse struct {
|
||||
Address Address `json:"address,omitempty"`
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r getAddressResponse) error() error { return r.Err }
|
||||
|
||||
type postAddressRequest struct {
|
||||
ProfileID string
|
||||
Address Address
|
||||
}
|
||||
|
||||
type postAddressResponse struct {
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r postAddressResponse) error() error { return r.Err }
|
||||
|
||||
type deleteAddressRequest struct {
|
||||
ProfileID string
|
||||
AddressID string
|
||||
}
|
||||
|
||||
type deleteAddressResponse struct {
|
||||
Err error `json:"err,omitempty"`
|
||||
}
|
||||
|
||||
func (r deleteAddressResponse) error() error { return r.Err }
|
||||
88
vendor/github.com/go-kit/kit/examples/profilesvc/middlewares.go
generated
vendored
Normal file
88
vendor/github.com/go-kit/kit/examples/profilesvc/middlewares.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package profilesvc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
)
|
||||
|
||||
// Middleware describes a service (as opposed to endpoint) middleware.
|
||||
type Middleware func(Service) Service
|
||||
|
||||
func LoggingMiddleware(logger log.Logger) Middleware {
|
||||
return func(next Service) Service {
|
||||
return &loggingMiddleware{
|
||||
next: next,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type loggingMiddleware struct {
|
||||
next Service
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) PostProfile(ctx context.Context, p Profile) (err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "PostProfile", "id", p.ID, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.PostProfile(ctx, p)
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) GetProfile(ctx context.Context, id string) (p Profile, err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "GetProfile", "id", id, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.GetProfile(ctx, id)
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) PutProfile(ctx context.Context, id string, p Profile) (err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "PutProfile", "id", id, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.PutProfile(ctx, id, p)
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) PatchProfile(ctx context.Context, id string, p Profile) (err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "PatchProfile", "id", id, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.PatchProfile(ctx, id, p)
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) DeleteProfile(ctx context.Context, id string) (err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "DeleteProfile", "id", id, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.DeleteProfile(ctx, id)
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) GetAddresses(ctx context.Context, profileID string) (addresses []Address, err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "GetAddresses", "profileID", profileID, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.GetAddresses(ctx, profileID)
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) GetAddress(ctx context.Context, profileID string, addressID string) (a Address, err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "GetAddress", "profileID", profileID, "addressID", addressID, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.GetAddress(ctx, profileID, addressID)
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) PostAddress(ctx context.Context, profileID string, a Address) (err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "PostAddress", "profileID", profileID, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.PostAddress(ctx, profileID, a)
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) DeleteAddress(ctx context.Context, profileID string, addressID string) (err error) {
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log("method", "DeleteAddress", "profileID", profileID, "addressID", addressID, "took", time.Since(begin), "err", err)
|
||||
}(time.Now())
|
||||
return mw.next.DeleteAddress(ctx, profileID, addressID)
|
||||
}
|
||||
185
vendor/github.com/go-kit/kit/examples/profilesvc/service.go
generated
vendored
Normal file
185
vendor/github.com/go-kit/kit/examples/profilesvc/service.go
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
package profilesvc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Service is a simple CRUD interface for user profiles.
|
||||
type Service interface {
|
||||
PostProfile(ctx context.Context, p Profile) error
|
||||
GetProfile(ctx context.Context, id string) (Profile, error)
|
||||
PutProfile(ctx context.Context, id string, p Profile) error
|
||||
PatchProfile(ctx context.Context, id string, p Profile) error
|
||||
DeleteProfile(ctx context.Context, id string) error
|
||||
GetAddresses(ctx context.Context, profileID string) ([]Address, error)
|
||||
GetAddress(ctx context.Context, profileID string, addressID string) (Address, error)
|
||||
PostAddress(ctx context.Context, profileID string, a Address) error
|
||||
DeleteAddress(ctx context.Context, profileID string, addressID string) error
|
||||
}
|
||||
|
||||
// Profile represents a single user profile.
|
||||
// ID should be globally unique.
|
||||
type Profile struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Addresses []Address `json:"addresses,omitempty"`
|
||||
}
|
||||
|
||||
// Address is a field of a user profile.
|
||||
// ID should be unique within the profile (at a minimum).
|
||||
type Address struct {
|
||||
ID string `json:"id"`
|
||||
Location string `json:"location,omitempty"`
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInconsistentIDs = errors.New("inconsistent IDs")
|
||||
ErrAlreadyExists = errors.New("already exists")
|
||||
ErrNotFound = errors.New("not found")
|
||||
)
|
||||
|
||||
type inmemService struct {
|
||||
mtx sync.RWMutex
|
||||
m map[string]Profile
|
||||
}
|
||||
|
||||
func NewInmemService() Service {
|
||||
return &inmemService{
|
||||
m: map[string]Profile{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *inmemService) PostProfile(ctx context.Context, p Profile) error {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
if _, ok := s.m[p.ID]; ok {
|
||||
return ErrAlreadyExists // POST = create, don't overwrite
|
||||
}
|
||||
s.m[p.ID] = p
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *inmemService) GetProfile(ctx context.Context, id string) (Profile, error) {
|
||||
s.mtx.RLock()
|
||||
defer s.mtx.RUnlock()
|
||||
p, ok := s.m[id]
|
||||
if !ok {
|
||||
return Profile{}, ErrNotFound
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (s *inmemService) PutProfile(ctx context.Context, id string, p Profile) error {
|
||||
if id != p.ID {
|
||||
return ErrInconsistentIDs
|
||||
}
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
s.m[id] = p // PUT = create or update
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *inmemService) PatchProfile(ctx context.Context, id string, p Profile) error {
|
||||
if p.ID != "" && id != p.ID {
|
||||
return ErrInconsistentIDs
|
||||
}
|
||||
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
existing, ok := s.m[id]
|
||||
if !ok {
|
||||
return ErrNotFound // PATCH = update existing, don't create
|
||||
}
|
||||
|
||||
// We assume that it's not possible to PATCH the ID, and that it's not
|
||||
// possible to PATCH any field to its zero value. That is, the zero value
|
||||
// means not specified. The way around this is to use e.g. Name *string in
|
||||
// the Profile definition. But since this is just a demonstrative example,
|
||||
// I'm leaving that out.
|
||||
|
||||
if p.Name != "" {
|
||||
existing.Name = p.Name
|
||||
}
|
||||
if len(p.Addresses) > 0 {
|
||||
existing.Addresses = p.Addresses
|
||||
}
|
||||
s.m[id] = existing
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *inmemService) DeleteProfile(ctx context.Context, id string) error {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
if _, ok := s.m[id]; !ok {
|
||||
return ErrNotFound
|
||||
}
|
||||
delete(s.m, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *inmemService) GetAddresses(ctx context.Context, profileID string) ([]Address, error) {
|
||||
s.mtx.RLock()
|
||||
defer s.mtx.RUnlock()
|
||||
p, ok := s.m[profileID]
|
||||
if !ok {
|
||||
return []Address{}, ErrNotFound
|
||||
}
|
||||
return p.Addresses, nil
|
||||
}
|
||||
|
||||
func (s *inmemService) GetAddress(ctx context.Context, profileID string, addressID string) (Address, error) {
|
||||
s.mtx.RLock()
|
||||
defer s.mtx.RUnlock()
|
||||
p, ok := s.m[profileID]
|
||||
if !ok {
|
||||
return Address{}, ErrNotFound
|
||||
}
|
||||
for _, address := range p.Addresses {
|
||||
if address.ID == addressID {
|
||||
return address, nil
|
||||
}
|
||||
}
|
||||
return Address{}, ErrNotFound
|
||||
}
|
||||
|
||||
func (s *inmemService) PostAddress(ctx context.Context, profileID string, a Address) error {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
p, ok := s.m[profileID]
|
||||
if !ok {
|
||||
return ErrNotFound
|
||||
}
|
||||
for _, address := range p.Addresses {
|
||||
if address.ID == a.ID {
|
||||
return ErrAlreadyExists
|
||||
}
|
||||
}
|
||||
p.Addresses = append(p.Addresses, a)
|
||||
s.m[profileID] = p
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *inmemService) DeleteAddress(ctx context.Context, profileID string, addressID string) error {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
p, ok := s.m[profileID]
|
||||
if !ok {
|
||||
return ErrNotFound
|
||||
}
|
||||
newAddresses := make([]Address, 0, len(p.Addresses))
|
||||
for _, address := range p.Addresses {
|
||||
if address.ID == addressID {
|
||||
continue // delete
|
||||
}
|
||||
newAddresses = append(newAddresses, address)
|
||||
}
|
||||
if len(newAddresses) == len(p.Addresses) {
|
||||
return ErrNotFound
|
||||
}
|
||||
p.Addresses = newAddresses
|
||||
s.m[profileID] = p
|
||||
return nil
|
||||
}
|
||||
400
vendor/github.com/go-kit/kit/examples/profilesvc/transport.go
generated
vendored
Normal file
400
vendor/github.com/go-kit/kit/examples/profilesvc/transport.go
generated
vendored
Normal file
@@ -0,0 +1,400 @@
|
||||
package profilesvc
|
||||
|
||||
// The profilesvc is just over HTTP, so we just have a single transport.go.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
httptransport "github.com/go-kit/kit/transport/http"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrBadRouting is returned when an expected path variable is missing.
|
||||
// It always indicates programmer error.
|
||||
ErrBadRouting = errors.New("inconsistent mapping between route and handler (programmer error)")
|
||||
)
|
||||
|
||||
// MakeHTTPHandler mounts all of the service endpoints into an http.Handler.
|
||||
// Useful in a profilesvc server.
|
||||
func MakeHTTPHandler(s Service, logger log.Logger) http.Handler {
|
||||
r := mux.NewRouter()
|
||||
e := MakeServerEndpoints(s)
|
||||
options := []httptransport.ServerOption{
|
||||
httptransport.ServerErrorLogger(logger),
|
||||
httptransport.ServerErrorEncoder(encodeError),
|
||||
}
|
||||
|
||||
// POST /profiles/ adds another profile
|
||||
// GET /profiles/:id retrieves the given profile by id
|
||||
// PUT /profiles/:id post updated profile information about the profile
|
||||
// PATCH /profiles/:id partial updated profile information
|
||||
// DELETE /profiles/:id remove the given profile
|
||||
// GET /profiles/:id/addresses/ retrieve addresses associated with the profile
|
||||
// GET /profiles/:id/addresses/:addressID retrieve a particular profile address
|
||||
// POST /profiles/:id/addresses/ add a new address
|
||||
// DELETE /profiles/:id/addresses/:addressID remove an address
|
||||
|
||||
r.Methods("POST").Path("/profiles/").Handler(httptransport.NewServer(
|
||||
e.PostProfileEndpoint,
|
||||
decodePostProfileRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
r.Methods("GET").Path("/profiles/{id}").Handler(httptransport.NewServer(
|
||||
e.GetProfileEndpoint,
|
||||
decodeGetProfileRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
r.Methods("PUT").Path("/profiles/{id}").Handler(httptransport.NewServer(
|
||||
e.PutProfileEndpoint,
|
||||
decodePutProfileRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
r.Methods("PATCH").Path("/profiles/{id}").Handler(httptransport.NewServer(
|
||||
e.PatchProfileEndpoint,
|
||||
decodePatchProfileRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
r.Methods("DELETE").Path("/profiles/{id}").Handler(httptransport.NewServer(
|
||||
e.DeleteProfileEndpoint,
|
||||
decodeDeleteProfileRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
r.Methods("GET").Path("/profiles/{id}/addresses/").Handler(httptransport.NewServer(
|
||||
e.GetAddressesEndpoint,
|
||||
decodeGetAddressesRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
r.Methods("GET").Path("/profiles/{id}/addresses/{addressID}").Handler(httptransport.NewServer(
|
||||
e.GetAddressEndpoint,
|
||||
decodeGetAddressRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
r.Methods("POST").Path("/profiles/{id}/addresses/").Handler(httptransport.NewServer(
|
||||
e.PostAddressEndpoint,
|
||||
decodePostAddressRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
r.Methods("DELETE").Path("/profiles/{id}/addresses/{addressID}").Handler(httptransport.NewServer(
|
||||
e.DeleteAddressEndpoint,
|
||||
decodeDeleteAddressRequest,
|
||||
encodeResponse,
|
||||
options...,
|
||||
))
|
||||
return r
|
||||
}
|
||||
|
||||
func decodePostProfileRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
var req postProfileRequest
|
||||
if e := json.NewDecoder(r.Body).Decode(&req.Profile); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeGetProfileRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
vars := mux.Vars(r)
|
||||
id, ok := vars["id"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
return getProfileRequest{ID: id}, nil
|
||||
}
|
||||
|
||||
func decodePutProfileRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
vars := mux.Vars(r)
|
||||
id, ok := vars["id"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
var profile Profile
|
||||
if err := json.NewDecoder(r.Body).Decode(&profile); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return putProfileRequest{
|
||||
ID: id,
|
||||
Profile: profile,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodePatchProfileRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
vars := mux.Vars(r)
|
||||
id, ok := vars["id"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
var profile Profile
|
||||
if err := json.NewDecoder(r.Body).Decode(&profile); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return patchProfileRequest{
|
||||
ID: id,
|
||||
Profile: profile,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeDeleteProfileRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
vars := mux.Vars(r)
|
||||
id, ok := vars["id"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
return deleteProfileRequest{ID: id}, nil
|
||||
}
|
||||
|
||||
func decodeGetAddressesRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
vars := mux.Vars(r)
|
||||
id, ok := vars["id"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
return getAddressesRequest{ProfileID: id}, nil
|
||||
}
|
||||
|
||||
func decodeGetAddressRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
vars := mux.Vars(r)
|
||||
id, ok := vars["id"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
addressID, ok := vars["addressID"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
return getAddressRequest{
|
||||
ProfileID: id,
|
||||
AddressID: addressID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodePostAddressRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
vars := mux.Vars(r)
|
||||
id, ok := vars["id"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
var address Address
|
||||
if err := json.NewDecoder(r.Body).Decode(&address); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return postAddressRequest{
|
||||
ProfileID: id,
|
||||
Address: address,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeDeleteAddressRequest(_ context.Context, r *http.Request) (request interface{}, err error) {
|
||||
vars := mux.Vars(r)
|
||||
id, ok := vars["id"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
addressID, ok := vars["addressID"]
|
||||
if !ok {
|
||||
return nil, ErrBadRouting
|
||||
}
|
||||
return deleteAddressRequest{
|
||||
ProfileID: id,
|
||||
AddressID: addressID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodePostProfileRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("POST").Path("/profiles/")
|
||||
req.Method, req.URL.Path = "POST", "/profiles/"
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func encodeGetProfileRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("GET").Path("/profiles/{id}")
|
||||
r := request.(getProfileRequest)
|
||||
profileID := url.QueryEscape(r.ID)
|
||||
req.Method, req.URL.Path = "GET", "/profiles/"+profileID
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func encodePutProfileRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("PUT").Path("/profiles/{id}")
|
||||
r := request.(putProfileRequest)
|
||||
profileID := url.QueryEscape(r.ID)
|
||||
req.Method, req.URL.Path = "PUT", "/profiles/"+profileID
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func encodePatchProfileRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("PATCH").Path("/profiles/{id}")
|
||||
r := request.(patchProfileRequest)
|
||||
profileID := url.QueryEscape(r.ID)
|
||||
req.Method, req.URL.Path = "PATCH", "/profiles/"+profileID
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func encodeDeleteProfileRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("DELETE").Path("/profiles/{id}")
|
||||
r := request.(deleteProfileRequest)
|
||||
profileID := url.QueryEscape(r.ID)
|
||||
req.Method, req.URL.Path = "DELETE", "/profiles/"+profileID
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func encodeGetAddressesRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("GET").Path("/profiles/{id}/addresses/")
|
||||
r := request.(getAddressesRequest)
|
||||
profileID := url.QueryEscape(r.ProfileID)
|
||||
req.Method, req.URL.Path = "GET", "/profiles/"+profileID+"/addresses/"
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func encodeGetAddressRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("GET").Path("/profiles/{id}/addresses/{addressID}")
|
||||
r := request.(getAddressRequest)
|
||||
profileID := url.QueryEscape(r.ProfileID)
|
||||
addressID := url.QueryEscape(r.AddressID)
|
||||
req.Method, req.URL.Path = "GET", "/profiles/"+profileID+"/addresses/"+addressID
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func encodePostAddressRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("POST").Path("/profiles/{id}/addresses/")
|
||||
r := request.(postAddressRequest)
|
||||
profileID := url.QueryEscape(r.ProfileID)
|
||||
req.Method, req.URL.Path = "POST", "/profiles/"+profileID+"/addresses/"
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func encodeDeleteAddressRequest(ctx context.Context, req *http.Request, request interface{}) error {
|
||||
// r.Methods("DELETE").Path("/profiles/{id}/addresses/{addressID}")
|
||||
r := request.(deleteAddressRequest)
|
||||
profileID := url.QueryEscape(r.ProfileID)
|
||||
addressID := url.QueryEscape(r.AddressID)
|
||||
req.Method, req.URL.Path = "DELETE", "/profiles/"+profileID+"/addresses/"+addressID
|
||||
return encodeRequest(ctx, req, request)
|
||||
}
|
||||
|
||||
func decodePostProfileResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response postProfileResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func decodeGetProfileResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response getProfileResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func decodePutProfileResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response putProfileResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func decodePatchProfileResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response patchProfileResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func decodeDeleteProfileResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response deleteProfileResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func decodeGetAddressesResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response getAddressesResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func decodeGetAddressResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response getAddressResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func decodePostAddressResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response postAddressResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func decodeDeleteAddressResponse(_ context.Context, resp *http.Response) (interface{}, error) {
|
||||
var response deleteAddressResponse
|
||||
err := json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
// errorer is implemented by all concrete response types that may contain
|
||||
// errors. It allows us to change the HTTP response code without needing to
|
||||
// trigger an endpoint (transport-level) error. For more information, read the
|
||||
// big comment in endpoints.go.
|
||||
type errorer interface {
|
||||
error() error
|
||||
}
|
||||
|
||||
// encodeResponse is the common method to encode all response types to the
|
||||
// client. I chose to do it this way because, since we're using JSON, there's no
|
||||
// reason to provide anything more specific. It's certainly possible to
|
||||
// specialize on a per-response (per-method) basis.
|
||||
func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
|
||||
if e, ok := response.(errorer); ok && e.error() != nil {
|
||||
// Not a Go kit transport error, but a business-logic error.
|
||||
// Provide those as HTTP errors.
|
||||
encodeError(ctx, e.error(), w)
|
||||
return nil
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
// encodeRequest likewise JSON-encodes the request to the HTTP request body.
|
||||
// Don't use it directly as a transport/http.Client EncodeRequestFunc:
|
||||
// profilesvc endpoints require mutating the HTTP method and request path.
|
||||
func encodeRequest(_ context.Context, req *http.Request, request interface{}) error {
|
||||
var buf bytes.Buffer
|
||||
err := json.NewEncoder(&buf).Encode(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Body = ioutil.NopCloser(&buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
func encodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||
if err == nil {
|
||||
panic("encodeError with nil error")
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(codeFrom(err))
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
func codeFrom(err error) int {
|
||||
switch err {
|
||||
case ErrNotFound:
|
||||
return http.StatusNotFound
|
||||
case ErrAlreadyExists, ErrInconsistentIDs:
|
||||
return http.StatusBadRequest
|
||||
default:
|
||||
return http.StatusInternalServerError
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user