Documentation ¶
Overview ¶
Package endpoints will let you write Cloud Endpoints backend in Go.
Usage ¶
Declare structs which describe your data. For instance:
// Greeting is a datastore entity that represents a single greeting. // It also serves as (a part of) a response of GreetingService. type Greeting struct { Key *datastore.Key `json:"id" datastore:"-"` Author string `json:"author"` Content string `json:"content" datastore:",noindex" endpoints:"req"` Date time.Time `json:"date"` } // GreetingsList is a response type of GreetingService.List method type GreetingsList struct { Items []*Greeting `json:"items"` } // Request type for GreetingService.List type GreetingsListReq struct { Limit int `json:"limit" endpoints:"d=10"` }
Then, a service:
// GreetingService can sign the guesbook, list all greetings and delete // a greeting from the guestbook. type GreetingService struct { } // List responds with a list of all greetings ordered by Date field. // Most recent greets come first. func (gs *GreetingService) List(c context.Context, r *GreetingsListReq) (*GreetingsList, error) { if r.Limit <= 0 { r.Limit = 10 } q := datastore.NewQuery("Greeting").Order("-Date").Limit(r.Limit) greets := make([]*Greeting, 0, r.Limit) keys, err := q.GetAll(c, &greets) if err != nil { return nil, err } for i, k := range keys { greets[i].Key = k } return &GreetingsList{greets}, nil }
Last step is to make the above available as a discoverable API and leverage all the juicy stuff Cloud Endpoints are great at.
import "github.com/GoogleCloudPlatform/go-endpoints/endpoints" func init() { greetService := &GreetingService{} api, err := endpoints.RegisterService(greetService, "greeting", "v1", "Greetings API", true) if err != nil { panic(err.Error()) } info := api.MethodByName("List").Info() info.Name, info.HTTPMethod, info.Path, info.Desc = "greets.list", "GET", "greetings", "List most recent greetings." endpoints.HandleHTTP() }
Don't forget to add URL matching in app.yaml:
application: my-app-id version: v1 threadsafe: true runtime: go api_version: go1 handlers: - url: /.* script: _go_app # Important! Even though there's a catch all routing above, # without these two lines it's not going to work. # Make sure you have this: - url: /_ah/spi/.* script: _go_app
That's it. It is time to start dev server and enjoy the discovery doc: http://localhost:8080/_ah/api/explorer
Custom types ¶
You can define your own types and use them directly as a field type in a service method request/response as long as they implement json.Marshaler and json.Unmarshaler interfaces.
Let's say we have this method:
func (s *MyService) ListItems(c context.Context, r *ListReq) (*ItemsList, error) { // fetch a list of items }
where ListReq and ItemsList are defined as follows:
type ListReq struct { Limit int `json:"limit,string" endpoints:"d=10,max=100"` Page *QueryMarker `json:"cursor"` } type ItemsList struct { Items []*Item `json:"items"` Next *QueryMarker `json:"next,omitempty"` }
What's interesting here is ListReq.Page and ItemsList.Next fields which are of type QueryMarker:
import "appengine/datastore" type QueryMarker struct { datastore.Cursor } func (qm *QueryMarker) MarshalJSON() ([]byte, error) { return []byte(`"` + qm.String() + `"`), nil } func (qm *QueryMarker) UnmarshalJSON(buf []byte) error { if len(buf) < 2 || buf[0] != '"' || buf[len(buf)-1] != '"' { return errors.New("QueryMarker: bad cursor value") } cursor, err := datastore.DecodeCursor(string(buf[1 : len(buf)-1])) if err != nil { return err } *qm = QueryMarker{cursor} return nil }
Now that our QueryMarker implements required interfaces we can use ListReq.Page field as if it were a `datastore.Cursor` in our service method, for instance:
func (s *MyService) ListItems(c context.Context, r *ListReq) (*ItemsList, error) { list := &ItemsList{Items: make([]*Item, 0, r.Limit)} q := datastore.NewQuery("Item").Limit(r.Limit) if r.Page != nil { q = q.Start(r.Page.Cursor) } var iter *datastore.Iterator for iter := q.Run(c); ; { var item Item key, err := iter.Next(&item) if err == datastore.Done { break } if err != nil { return nil, err } item.Key = key list.Items = append(list.Items, &item) } cur, err := iter.Cursor() if err != nil { return nil, err } list.Next = &QueryMarker{cur} return list, nil }
A serialized ItemsList would then look something like this:
{ "items": [ { "id": "5629499534213120", "name": "A TV set", "price": 123.45 } ], "next": "E-ABAIICImoNZGV2fmdvcGhtYXJrc3IRCxIEVXNlchiAgICAgICACgwU" }
Another nice thing about this is, some types in appengine/datastore package already implement json.Marshal and json.Unmarshal.
Take, for instance, datastore.Key. I could use it as an ID in my JSON response out of the box, if I wanted to:
type User struct { Key *datastore.Key `json:"id" datastore:"-"` Name string `json:"name" datastore:"name"` Role string `json:"role" datastore:"role"` Email string `json:"email" datastore:"email"` } type GetUserReq struct { Key *datastore.Key `json:"id"` } // defined with "users/{id}" path template func (s *MyService) GetUser(c context.Context, r *GetUserReq) (*User, error) { user := &User{} if err := datastore.Get(c, r.Key, user); err != nil { return nil, err } user.Key = r.Key return user, nil }
JSON would then look something like this:
GET /_ah/api/myapi/v1/users/ag1kZXZ-Z29waG1hcmtzchELEgRVc2VyGICAgICAgIAKDA { "id": "ag1kZXZ-Z29waG1hcmtzchELEgRVc2VyGICAgICAgIAKDA", "name": "John Doe", "role": "member", "email": "user@example.org" }
Field tags ¶
Go Endpoints has its own field tag "endpoints" which you can use to let your clients know what a service method data constraints are (on input):
- req, means "required".
- d, default value, cannot be used together with req.
- min and max constraints. Can be used only on int and uint (8/16/32/64 bits).
- desc, a field description. Cannot contain a "," (comma) for now.
Let's see an example:
type TaggedStruct struct { A int `endpoints:"req,min=0,max=100,desc=An int field"` B int `endpoints:"d=10,min=1,max=200"` C string `endpoints:"req,d=Hello gopher,desc=A string field"` } - A field is required and has min & max constrains, is described as "An int field" - B field is not required, defaults to 10 and has min & max constrains - C field is required, defaults to "Hello gopher", is described as "A string field"
JSON tag and path templates ¶
You can use JSON tags to shape your service method's response (the output).
Endpoints will honor Go's encoding/json marshaling rules (http://golang.org/pkg/encoding/json/#Marshal), which means having this struct:
type TaggedStruct struct { A int B int `json:"myB"` C string `json:"c"` Skipped int `json:"-"` }
a service method path template could then look like:
some/path/{A}/other/{c}/{myB}
Notice, the names are case-sensitive.
Naturally, you can combine json and endpoints tags to use a struct for both input and output:
type TaggedStruct struct { A int `endpoints:"req,min=0,max=100,desc=An int field"` B int `json:"myB" endpoints:"d=10,min=1,max=200"` C string `json:"c" endpoints:"req,d=Hello gopher,desc=A string field"` Skipped int `json:"-"` }
Long integers (int64, uint64)
As per Type and Format Summary (https://developers.google.com/discovery/v1/type-format):
a 64-bit integer cannot be represented in JSON (since JavaScript and JSON support integers up to 2^53). Therefore, a 64-bit integer must be represented as a string in JSON requests/responses
In this case, it is sufficient to append ",string" to the json tag:
type Int64Struct struct { Id int64 `json:",string"` }
Generate client libraries ¶
Once an app is deployed on appspot.com, we can use the discovery doc to generate libraries for different clients.
Android
$ URL='https://my-app-id.appspot.com/_ah/api/discovery/v1/apis/greeting/v1/rest' $ curl -s $URL > greetings.rest.discovery # Optionally check the discovery doc $ less greetings.rest.discovery $ GO_SDK/endpointscfg.py gen_client_lib java greetings.rest.discovery
You should be able to find ./greetings.rest.zip file with Java client source code and its dependencies.
Once you have that, follow the official guide https://developers.google.com/appengine/docs/python/endpoints/consume_android.
iOS
# Note the rpc suffix in the URL: $ URL='https://my-app-id.appspot.com/_ah/api/discovery/v1/apis/greeting/v1/rpc' $ curl -s $URL > greetings.rpc.discovery # optionally check the discovery doc $ less greetings.rpc.discovery
Then, feed greetings.rpc.discovery file to the library generator on OS X as described in the official guide: https://developers.google.com/appengine/docs/python/endpoints/consume_ios
JavaScript ¶
There's really nothing to generate for JavaScript, you just use it!
Here's the official guide: https://developers.google.com/appengine/docs/python/endpoints/consume_js
Other docs ¶
Wiki pages on the github repo: https://github.com/crhym3/go-endpoints/wiki
Samples ¶
Check out TicTacToe sample: https://github.com/crhym3/go-tictactoe
Or play it on the live demo app at https://go-endpoints.appspot.com/tictactoe
Running tests ¶
We currently use aet tool (https://github.com/crhym3/aegot) to simplify running tests on files that have "appengine" or "appengine_internal" imports.
Check out the readme of that tool but, assuming you cloned this repo (so you can reach ./endpoints dir), the initial setup process is pretty simple:
- go get github.com/crhym3/aegot/aet
- aet init ./endpoints
That's it. You should be able to run tests with "aet test ./endpoints" now.
Index ¶
- Constants
- Variables
- func CurrentBearerTokenScope(c context.Context, scopes []string, clientIDs []string) (string, error)
- func CurrentBearerTokenUser(c context.Context, scopes []string, clientIDs []string) (*user.User, error)
- func CurrentUser(c context.Context, scopes []string, audiences []string, clientIDs []string) (*user.User, error)
- func HTTPRequest(c context.Context) *http.Request
- func HandleHTTP()
- func NewAPIError(name string, msg string, code int) error
- func NewBadRequestError(format string, args ...interface{}) error
- func NewConflictError(format string, args ...interface{}) error
- func NewContext(r *http.Request) context.Context
- func NewForbiddenError(format string, args ...interface{}) error
- func NewInternalServerError(format string, args ...interface{}) error
- func NewNotFoundError(format string, args ...interface{}) error
- func NewUnauthorizedError(format string, args ...interface{}) error
- type APIConfigsList
- type APIDescriptor
- type APIEnumParamSpec
- type APIError
- type APIMethod
- type APIMethodDescriptor
- type APIReqRespDescriptor
- type APIRequestParamSpec
- type APISchemaDescriptor
- type APISchemaProperty
- type APISchemaRef
- type Authenticator
- type BackendService
- func (s *BackendService) GetApiConfigs(r *http.Request, req *GetAPIConfigsRequest, resp *APIConfigsList) error
- func (s *BackendService) GetFirstConfig(r *http.Request, _ *VoidMessage, resp *APIDescriptor) error
- func (s *BackendService) LogMessages(r *http.Request, req *LogMessagesRequest, _ *VoidMessage) error
- type GetAPIConfigsRequest
- type LogMessage
- type LogMessagesRequest
- type MethodInfo
- type RPCService
- type Server
- func (s *Server) HandleHTTP(mux *http.ServeMux)
- func (s *Server) RegisterService(srv interface{}, name, ver, desc string, isDefault bool) (*RPCService, error)
- func (s *Server) RegisterServiceWithDefaults(srv interface{}) (*RPCService, error)
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *Server) ServiceByName(serviceName string) *RPCService
- type ServiceInfo
- type ServiceMethod
- type VoidMessage
Constants ¶
const ( // DefaultCertURI is Google's public URL which points to JWT certs. DefaultCertURI = ("https://www.googleapis.com/service_accounts/" + "v1/metadata/raw/federated-signon@system.gserviceaccount.com") // EmailScope is Google's OAuth 2.0 email scope EmailScope = "https://www.googleapis.com/auth/userinfo.email" // TokeninfoURL is Google's OAuth 2.0 access token verification URL TokeninfoURL = "https://www.googleapis.com/oauth2/v1/tokeninfo" // APIExplorerClientID is the client ID of API explorer. APIExplorerClientID = "292824132082.apps.googleusercontent.com" )
Variables ¶
var ( // InternalServerError is default error with http.StatusInternalServerError (500) InternalServerError = NewInternalServerError("") // BadRequestError is default error with http.StatusBadRequest (400) BadRequestError = NewBadRequestError("") UnauthorizedError = NewUnauthorizedError("") // ForbiddenError is default error with http.StatusForbidden (403) ForbiddenError = NewForbiddenError("") // NotFoundError is default error with http.StatusNotFound (404) NotFoundError = NewNotFoundError("") // ConflictError is default error with http.StatusConflict (409) ConflictError = NewConflictError("") )
var ( // AuthenticatorFactory creates a new Authenticator. // // It is a variable on purpose. You can set it to a stub implementation // in tests. AuthenticatorFactory func() Authenticator )
var ( // SchemaNameForType returns a name for the given schema type, // used to reference schema definitions in the API descriptor. // // Default is to return just the type name, which does not guarantee // uniqueness if you have identically named structs in different packages. // // You can override this function, for instance to prefix all of your schemas // with a custom name. It should start from an uppercase letter and contain // only [a-zA-Z0-9]. SchemaNameForType = func(t reflect.Type) string { return t.Name() } )
Functions ¶
func CurrentBearerTokenScope ¶
func CurrentBearerTokenScope(c context.Context, scopes []string, clientIDs []string) (string, error)
CurrentBearerTokenScope compares given scopes and clientIDs with those in c.
Both scopes and clientIDs args must have at least one element.
Returns a single scope (one of provided scopes) if the two conditions are met:
- it is found in Context c
- client ID on that scope matches one of clientIDs in the args
func CurrentBearerTokenUser ¶
func CurrentBearerTokenUser(c context.Context, scopes []string, clientIDs []string) (*user.User, error)
CurrentBearerTokenUser returns a user associated with the request which is expected to have a Bearer token.
Both scopes and clientIDs must have at least one element.
Returns an error if the client did not make a valid request, or none of clientIDs are allowed to make requests, or user did not authorize any of the scopes.
func CurrentUser ¶
func CurrentUser(c context.Context, scopes []string, audiences []string, clientIDs []string) (*user.User, error)
CurrentUser checks for both JWT and Bearer tokens.
It first tries to decode and verify JWT token (if conditions are met) and falls back to Bearer token.
The returned user will have only ID, Email and ClientID fields set. User.ID is a Google Account ID, which is different from GAE user ID. For more info on User.ID see 'sub' claim description on https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo
func HTTPRequest ¶
HTTPRequest returns the request associated with a context.
func HandleHTTP ¶
func HandleHTTP()
HandleHTTP calls DefaultServer's HandleHTTP method using default serve mux.
func NewAPIError ¶
NewAPIError Create a new APIError for custom error
func NewBadRequestError ¶
NewBadRequestError creates a new APIError with Bad Request status (400)
func NewConflictError ¶
NewConflictError creates a new APIError with Conflict status (409)
func NewContext ¶
NewContext returns a new context for an in-flight API (HTTP) request.
func NewForbiddenError ¶
NewForbiddenError creates a new APIError with Forbidden status (403)
func NewInternalServerError ¶
NewInternalServerError creates a new APIError with Internal Server Error status (500)
func NewNotFoundError ¶
NewNotFoundError creates a new APIError with Not Found status (404)
func NewUnauthorizedError ¶
NewUnauthorizedError creates a new APIError with Unauthorized status (401)
Types ¶
type APIConfigsList ¶
type APIConfigsList struct {
Items []string `json:"items"`
}
APIConfigsList is the response scheme for BackendService.getApiConfigs method.
type APIDescriptor ¶
type APIDescriptor struct { // Required Extends string `json:"extends"` Root string `json:"root"` Name string `json:"name"` Version string `json:"version"` Default bool `json:"defaultVersion"` Abstract bool `json:"abstract"` Adapter struct { Bns string `json:"bns"` Type string `json:"type"` } `json:"adapter"` // Optional Cname string `json:"canonicalName,omitempty"` Desc string `json:"description,omitempty"` Auth *struct { AllowCookie bool `json:"allowCookieAuth"` } `json:"auth,omitempty"` // $METHOD_MAP Methods map[string]*APIMethod `json:"methods"` // $SCHEMA_DESCRIPTOR Descriptor struct { Methods map[string]*APIMethodDescriptor `json:"methods"` Schemas map[string]*APISchemaDescriptor `json:"schemas"` } `json:"descriptor"` }
APIDescriptor is the top-level struct for a single Endpoints API config.
type APIEnumParamSpec ¶
type APIEnumParamSpec struct { BackendVal string `json:"backendValue"` Desc string `json:"description,omitempty"` }
APIEnumParamSpec is the enum type of request/response param spec. Not used currently.
type APIMethod ¶
type APIMethod struct { Path string `json:"path"` HTTPMethod string `json:"httpMethod"` RosyMethod string `json:"rosyMethod"` Request APIReqRespDescriptor `json:"request"` Response APIReqRespDescriptor `json:"response"` Scopes []string `json:"scopes,omitempty"` Audiences []string `json:"audiences,omitempty"` ClientIds []string `json:"clientIds,omitempty"` Desc string `json:"description,omitempty"` }
APIMethod is an item of $METHOD_MAP
type APIMethodDescriptor ¶
type APIMethodDescriptor struct { Request *APISchemaRef `json:"request,omitempty"` Response *APISchemaRef `json:"response,omitempty"` // contains filtered or unexported fields }
APIMethodDescriptor item of Descriptor.Methods map ($SCHEMA_DESCRIPTOR).
type APIReqRespDescriptor ¶
type APIReqRespDescriptor struct { Body string `json:"body"` BodyName string `json:"bodyName,omitempty"` Params map[string]*APIRequestParamSpec `json:"parameters,omitempty"` }
APIReqRespDescriptor indicates type of request data expected to be found in a request or a response.
type APIRequestParamSpec ¶
type APIRequestParamSpec struct { Type string `json:"type"` Required bool `json:"required,omitempty"` Default interface{} `json:"default,omitempty"` Repeated bool `json:"repeated,omitempty"` Enum map[string]*APIEnumParamSpec `json:"enum,omitempty"` // only for int32/int64/uint32/uint64 Min interface{} `json:"minValue,omitempty"` Max interface{} `json:"maxValue,omitempty"` }
APIRequestParamSpec is a description of all the expected request parameters.
type APISchemaDescriptor ¶
type APISchemaDescriptor struct { ID string `json:"id"` Type string `json:"type"` Properties map[string]*APISchemaProperty `json:"properties"` Desc string `json:"description,omitempty"` }
APISchemaDescriptor item of Descriptor.Schemas map ($SCHEMA_DESCRIPTOR)
type APISchemaProperty ¶
type APISchemaProperty struct { Type string `json:"type,omitempty"` Format string `json:"format,omitempty"` Items *APISchemaProperty `json:"items,omitempty"` Required bool `json:"required,omitempty"` Default interface{} `json:"default,omitempty"` Ref string `json:"$ref,omitempty"` Desc string `json:"description,omitempty"` }
APISchemaProperty is an item of APISchemaDescriptor.Properties map
type APISchemaRef ¶
type APISchemaRef struct {
Ref string `json:"$ref"`
}
APISchemaRef is used when referencing a schema from a method or array elem.
type Authenticator ¶
type Authenticator interface { // CurrentOAuthClientID returns a clientID associated with the scope. CurrentOAuthClientID(ctx context.Context, scope string) (string, error) // CurrentOAuthUser returns a user of this request for the given scope. // It caches OAuth info at the first call for future invocations. // // Returns an error if data for this scope is not available. CurrentOAuthUser(ctx context.Context, scope string) (*user.User, error) }
An Authenticator can identify the current user.
type BackendService ¶
type BackendService struct {
// contains filtered or unexported fields
}
BackendService is an API config enumeration service used by Google API Server.
This is a simple API providing a list of APIs served by this App Engine instance. It is called by the Google API Server during app deployment to get an updated interface for each of the supported APIs.
func (*BackendService) GetApiConfigs ¶
func (s *BackendService) GetApiConfigs( r *http.Request, req *GetAPIConfigsRequest, resp *APIConfigsList) error
GetApiConfigs creates APIDescriptor for every registered RPCService and responds with a config suitable for generating Discovery doc.
Responds with a list of active APIs and their configuration files.
func (*BackendService) GetFirstConfig ¶
func (s *BackendService) GetFirstConfig( r *http.Request, _ *VoidMessage, resp *APIDescriptor) error
GetFirstConfig is a test method and will be removed sooner or later.
func (*BackendService) LogMessages ¶
func (s *BackendService) LogMessages( r *http.Request, req *LogMessagesRequest, _ *VoidMessage) error
LogMessages writes a log message from the Swarm FE to the log.
type GetAPIConfigsRequest ¶
type GetAPIConfigsRequest struct {
AppRevision string `json:"appRevision"`
}
GetAPIConfigsRequest is the request scheme for fetching API configs.
type LogMessage ¶
type LogMessage struct { Level logLevel `json:"level"` Message string `json:"message" endpoints:"required"` }
LogMessage is a single log message within a LogMessagesRequest.
type LogMessagesRequest ¶
type LogMessagesRequest struct {
Messages []*LogMessage `json:"messages"`
}
LogMessagesRequest is the request body for log messages sent by Swarm FE.
type MethodInfo ¶
type MethodInfo struct { // name can also contain resource, e.g. "greets.list" Name string Path string HTTPMethod string Scopes []string Audiences []string ClientIds []string Desc string }
MethodInfo is what's used to construct Endpoints API config
type RPCService ¶
type RPCService struct {
// contains filtered or unexported fields
}
RPCService represents a service registered with a specific Server.
func Must ¶
func Must(s *RPCService, err error) *RPCService
Must is a helper that wraps a call to a function returning (*Template, error) and panics if the error is non-nil. It is intended for use in variable initializations such as:
var s = endpoints.Must(endpoints.RegisterService(s, "Service", "v1", "some service", true))
func RegisterService ¶
func RegisterService(srv interface{}, name, ver, desc string, isDefault bool) ( *RPCService, error)
RegisterService registers a service using DefaultServer. See Server.RegisterService for details.
func RegisterServiceWithDefaults ¶
func RegisterServiceWithDefaults(srv interface{}) (*RPCService, error)
RegisterServiceWithDefaults registers a service using DefaultServer. See Server.RegisterServiceWithDefaults for details.
func (*RPCService) APIDescriptor ¶
func (s *RPCService) APIDescriptor(dst *APIDescriptor, host string) error
APIDescriptor populates provided APIDescriptor with all info needed to generate a discovery doc from its receiver.
Args:
- dst, a non-nil pointer to APIDescriptor struct
- host, a hostname used for discovery API config Root and BNS.
Returns error if malformed params were encountered (e.g. ServerMethod.Path, etc.)
func (*RPCService) Info ¶
func (s *RPCService) Info() *ServiceInfo
Info returns a ServiceInfo which is used to construct Endpoints API config
func (*RPCService) MethodByName ¶
func (s *RPCService) MethodByName(name string) *ServiceMethod
MethodByName returns a ServiceMethod of a registered service's method or nil.
func (*RPCService) Methods ¶
func (s *RPCService) Methods() []*ServiceMethod
Methods returns a slice of all service's registered methods
func (*RPCService) Name ¶
func (s *RPCService) Name() string
Name returns service method name TODO: remove or use info.Name here?
type Server ¶
type Server struct { // ContextDecorator will be called as the last step of the creation of a new context. // If nil the context will not be decorated. ContextDecorator func(context.Context) (context.Context, error) // contains filtered or unexported fields }
Server serves registered RPC services using registered codecs.
var DefaultServer *Server
DefaultServer is the default RPC server, so you don't have to explicitly create one.
func (*Server) HandleHTTP ¶
HandleHTTP adds Server s to specified http.ServeMux. If no mux is provided http.DefaultServeMux will be used.
func (*Server) RegisterService ¶
func (s *Server) RegisterService(srv interface{}, name, ver, desc string, isDefault bool) (*RPCService, error)
RegisterService adds a new service to the server.
The name parameter is optional: if empty it will be inferred from the receiver type name.
Methods from the receiver will be extracted if these rules are satisfied:
- The receiver is exported (begins with an upper case letter) or local (defined in the package registering the service).
- The method name is exported.
- The method has either 2 arguments and 2 return values: *http.Request|Context, *arg => *reply, error or 3 arguments and 1 return value: *http.Request|Context, *arg, *reply => error
- The first argument is either *http.Request or Context.
- Second argument (*arg) and *reply are exported or local.
- First argument, *arg and *reply are all pointers.
- First (or second, if method has 2 arguments) return value is of type error.
All other methods are ignored.
func (*Server) RegisterServiceWithDefaults ¶
func (s *Server) RegisterServiceWithDefaults(srv interface{}) (*RPCService, error)
RegisterServiceWithDefaults will register provided service and will try to infer Endpoints config params from its method names and types. See RegisterService for details.
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP is Server's implementation of http.Handler interface.
func (*Server) ServiceByName ¶
func (s *Server) ServiceByName(serviceName string) *RPCService
ServiceByName returns a registered service or nil if there's no service registered by that name.
type ServiceInfo ¶
ServiceInfo is used to construct Endpoints API config
type ServiceMethod ¶
type ServiceMethod struct { // Type of the request data structure ReqType reflect.Type // Type of the response data structure RespType reflect.Type // contains filtered or unexported fields }
ServiceMethod is what represents a method of a registered service
func (*ServiceMethod) Info ¶
func (m *ServiceMethod) Info() *MethodInfo
Info returns a MethodInfo struct of a registered service's method
type VoidMessage ¶
type VoidMessage struct{}
VoidMessage represents the fact that a service method does not expect anything in a request (or a response).