Version: v0.0.0-...-ffa566b Latest Latest

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

Go to latest
Published: Mar 27, 2018 License: Apache-2.0 Imports: 24 Imported by: 9



Package endpoints will let you write Cloud Endpoints backend in Go.


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 {

  info := api.MethodByName("List").Info()
  info.Name, info.HTTPMethod, info.Path, info.Desc =
    "greets.list", "GET", "greetings", "List most recent greetings."


Don't forget to add URL matching in app.yaml:

application: my-app-id
version: v1
threadsafe: true

runtime: go
api_version: go1

- 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 {

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 {
        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:


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.


$ 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.


# 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


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


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.



View Source
const (
	// DefaultCertURI is Google's public URL which points to JWT certs.
	DefaultCertURI = ("https://www.googleapis.com/service_accounts/" +
	// 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"


View Source
var (

	// InternalServerError is default error with http.StatusInternalServerError (500)
	InternalServerError = NewInternalServerError("")
	// BadRequestError is default error with http.StatusBadRequest (400)
	BadRequestError = NewBadRequestError("")
	// UnauthorizedError is default error with http.StatusUnauthorized (401)
	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("")
View Source
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
View Source
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()


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

func HTTPRequest(c context.Context) *http.Request

HTTPRequest returns the request associated with a context.

func HandleHTTP

func HandleHTTP()

HandleHTTP calls DefaultServer's HandleHTTP method using default serve mux.

func NewAPIError

func NewAPIError(name string, msg string, code int) error

NewAPIError Create a new APIError for custom error

func NewBadRequestError

func NewBadRequestError(format string, args ...interface{}) error

NewBadRequestError creates a new APIError with Bad Request status (400)

func NewConflictError

func NewConflictError(format string, args ...interface{}) error

NewConflictError creates a new APIError with Conflict status (409)

func NewContext

func NewContext(r *http.Request) context.Context

NewContext returns a new context for an in-flight API (HTTP) request.

func NewForbiddenError

func NewForbiddenError(format string, args ...interface{}) error

NewForbiddenError creates a new APIError with Forbidden status (403)

func NewInternalServerError

func NewInternalServerError(format string, args ...interface{}) error

NewInternalServerError creates a new APIError with Internal Server Error status (500)

func NewNotFoundError

func NewNotFoundError(format string, args ...interface{}) error

NewNotFoundError creates a new APIError with Not Found status (404)

func NewUnauthorizedError

func NewUnauthorizedError(format string, args ...interface{}) error

NewUnauthorizedError creates a new APIError with Unauthorized status (401)


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"`

	Methods map[string]*APIMethod `json:"methods"`

	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 APIError

type APIError struct {
	Name string
	Msg  string
	Code int

APIError is a user custom API's error

func (*APIError) Error

func (a *APIError) Error() string

APIError is an error

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.


  • 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 NewServer

func NewServer(root string) *Server

NewServer returns a new RPC server.

func (*Server) HandleHTTP

func (s *Server) HandleHTTP(mux *http.ServeMux)

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

type ServiceInfo struct {
	Name        string
	Version     string
	Default     bool
	Description string

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).

Jump to

Keyboard shortcuts

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