Documentation
¶
Overview ¶
Package res provides RES service implementations for realtime API's through Resgate:
https://github.com/resgateio/resgate
The implementation provides low level methods to listen to and handle incoming requests, and to send events.
Concurrency ¶
Requests are handled concurrently for multiple resources, but the package guarantees that only one goroutine is executing handlers for any unique resource at any one time. This allows handlers to modify models and collections without additional synchronization such as mutexes.
Usage ¶
Create a new service:
s := res.NewService("myservice")
Add handlers for a model resource:
mymodel := map[string]interface{}{"name": "foo", "value": 42} s.Handle("mymodel", res.Access(res.AccessGranted), res.GetModel(func(r res.ModelRequest) { r.Model(mymodel) }), )
Add handlers for a collection resource:
mycollection := []string{"first", "second", "third"} s.Handle("mycollection", res.Access(res.AccessGranted), res.GetCollection(func(r res.CollectionRequest) { r.Collection(mycollection) }), )
Add handlers for parameterized resources:
s.Handle("article.$id", res.Access(res.AccessGranted), res.GetModel(func(r res.ModelRequest) { article := getArticle(r.PathParam("id")) if article == nil { r.NotFound() } else { r.Model(article) } }), )
Add handlers for method calls:
s.Handle("math", res.Access(res.AccessGranted), res.Call("double", func(r res.CallRequest) { var p struct { Value int `json:"value"` } r.ParseParams(&p) r.OK(p.Value * 2) }), )
Send change event on model update:
s.With("myservice.mymodel", func(r res.Resource) { mymodel["name"] = "bar" r.ChangeEvent(map[string]interface{}{"name": "bar"}) })
Send add event on collection update:
s.With("myservice.mycollection", func(r res.Resource) { mycollection = append(mycollection, "fourth") r.AddEvent("fourth", len(mycollection)-1) })
Add handlers for authentication:
s.Handle("myauth", res.Auth("login", func(r res.AuthRequest) { var p struct { Password string `json:"password"` } r.ParseParams(&p) if p.Password != "mysecret" { r.InvalidParams("Wrong password") } else { r.TokenEvent(map[string]string{"user": "admin"}) r.OK(nil) } }), )
Add handlers for access control:
s.Handle("mymodel",
res.Access(func(r res.AccessRequest) { var t struct { User string `json:"user"` } r.ParseToken(&t) if t.User == "admin" { r.AccessGranted() } else { r.AccessDenied() } }), res.GetModel(func(r res.ModelRequest) { r.Model(mymodel) }),
)
Start service:
s.ListenAndServe("nats://localhost:4222")
Index ¶
- Constants
- Variables
- type AccessHandler
- type AccessRequest
- type ApplyAddHandler
- type ApplyChangeHandler
- type ApplyCreateHandler
- type ApplyDeleteHandler
- type ApplyRemoveHandler
- type AuthHandler
- type AuthRequest
- type CallHandler
- type CallRequest
- type CollectionHandler
- type CollectionRequest
- type Conn
- type Error
- type Event
- type GetHandler
- type GetRequest
- type Handler
- type Match
- type ModelHandler
- type ModelRequest
- type Mux
- func (m *Mux) AddHandler(pattern string, hs Handler)
- func (m *Mux) AddListener(pattern string, handler func(*Event))
- func (m *Mux) Contains(test func(h Handler) bool) bool
- func (m *Mux) FullPath() string
- func (m *Mux) GetHandler(rname string) *Match
- func (m *Mux) Handle(pattern string, hf ...Option)
- func (m *Mux) Mount(path string, sub *Mux)
- func (m *Mux) Path() string
- func (m *Mux) Register(s *Service)
- func (m *Mux) Route(subpath string, fn func(m *Mux)) *Mux
- func (m *Mux) ValidateListeners() (err error)
- type NewHandlerdeprecated
- type NewRequest
- type Option
- func Access(h AccessHandler) Option
- func ApplyAdd(h ApplyAddHandler) Option
- func ApplyChange(h ApplyChangeHandler) Option
- func ApplyCreate(h ApplyCreateHandler) Option
- func ApplyDelete(h ApplyDeleteHandler) Option
- func ApplyRemove(h ApplyRemoveHandler) Option
- func Auth(method string, h AuthHandler) Option
- func Call(method string, h CallHandler) Option
- func GetCollection(h CollectionHandler) Option
- func GetModel(h ModelHandler) Option
- func GetResource(h GetHandler) Option
- func Group(group string) Option
- func New(h NewHandler) Optiondeprecated
- func OnRegister(callback func(service *Service, pattern Pattern, rh Handler)) Option
- func Set(h CallHandler) Option
- type OptionFunc
- type Pattern
- type QueryRequest
- type Ref
- type Request
- func (r *Request) Access(get bool, call string)
- func (r *Request) AccessDenied()
- func (r *Request) AccessGranted()
- func (r *Request) AddEvent(v interface{}, idx int)
- func (r *Request) CID() string
- func (r *Request) ChangeEvent(changed map[string]interface{})
- func (r *Request) Collection(collection interface{})
- func (r *Request) CreateEvent(data interface{})
- func (r *Request) DeleteEvent()
- func (r *Request) Error(err error)
- func (r *Request) Event(event string, payload interface{})
- func (r *Request) ForValue() bool
- func (r *Request) Group() string
- func (r *Request) Header() map[string][]string
- func (r *Request) Host() string
- func (r *Request) InvalidParams(message string)
- func (r *Request) InvalidQuery(message string)
- func (r *Request) Method() string
- func (r *Request) MethodNotFound()
- func (r *Request) Model(model interface{})
- func (r *Request) New(rid Ref)deprecated
- func (r *Request) NotFound()
- func (r *Request) OK(result interface{})
- func (r *Request) ParseParams(p interface{})
- func (r *Request) ParseQuery() url.Values
- func (r *Request) ParseToken(t interface{})
- func (r *Request) PathParam(key string) string
- func (r *Request) PathParams() map[string]string
- func (r *Request) Query() string
- func (r *Request) QueryCollection(collection interface{}, query string)
- func (r *Request) QueryEvent(cb func(QueryRequest))
- func (r *Request) QueryModel(model interface{}, query string)
- func (r *Request) RawParams() json.RawMessage
- func (r *Request) RawToken() json.RawMessage
- func (r *Request) ReaccessEvent()
- func (r *Request) RemoteAddr() string
- func (r *Request) RemoveEvent(idx int)
- func (r *Request) RequireValue() interface{}
- func (r *Request) ResetEvent()
- func (r *Request) Resource(rid string)
- func (r *Request) ResourceName() string
- func (r *Request) ResourceType() ResourceType
- func (r *Request) Service() *Service
- func (r *Request) Timeout(d time.Duration)
- func (r *Request) TokenEvent(token interface{})
- func (r *Request) Type() string
- func (r *Request) URI() string
- func (r *Request) Value() (interface{}, error)
- type Resource
- type ResourceType
- type Service
- func (s *Service) ListenAndServe(url string, options ...nats.Option) error
- func (s *Service) Logger() logger.Logger
- func (s *Service) ProtocolVersion() string
- func (s *Service) Reset(resources []string, access []string)
- func (s *Service) ResetAll()
- func (s *Service) Resource(rid string) (Resource, error)
- func (s *Service) Serve(nc Conn) error
- func (s *Service) SetLogger(l logger.Logger) *Service
- func (s *Service) SetOnDisconnect(f func(*Service))
- func (s *Service) SetOnError(f func(*Service, string))
- func (s *Service) SetOnReconnect(f func(*Service))
- func (s *Service) SetOnServe(f func(*Service))
- func (s *Service) SetOwnedResources(resources, access []string) *Service
- func (s *Service) SetQueryEventDuration(d time.Duration) *Service
- func (s *Service) SetReset(resources, access []string) *Servicedeprecated
- func (s *Service) Shutdown() error
- func (s *Service) TokenEvent(cid string, token interface{})
- func (s *Service) With(rid string, cb func(r Resource)) error
- func (s *Service) WithGroup(group string, cb func(s *Service))
- func (s *Service) WithResource(r Resource, cb func())
Constants ¶
const ( CodeAccessDenied = "system.accessDenied" CodeInternalError = "system.internalError" CodeInvalidParams = "system.invalidParams" CodeInvalidQuery = "system.invalidQuery" CodeMethodNotFound = "system.methodNotFound" CodeNotFound = "system.notFound" CodeTimeout = "system.timeout" )
Predefined error codes
const ( RequestTypeAccess = "access" RequestTypeGet = "get" RequestTypeCall = "call" RequestTypeAuth = "auth" )
Request types
Variables ¶
var ( ErrAccessDenied = &Error{Code: CodeAccessDenied, Message: "Access denied"} ErrInternalError = &Error{Code: CodeInternalError, Message: "Internal error"} ErrInvalidParams = &Error{Code: CodeInvalidParams, Message: "Invalid parameters"} ErrInvalidQuery = &Error{Code: CodeInvalidQuery, Message: "Invalid query"} ErrMethodNotFound = &Error{Code: CodeMethodNotFound, Message: "Method not found"} ErrNotFound = &Error{Code: CodeNotFound, Message: "Not found"} ErrTimeout = &Error{Code: CodeTimeout, Message: "Request timeout"} )
Predefined errors
var ( // Model sets handler type to model Model = OptionFunc(func(hs *Handler) { if hs.Type != TypeUnset { panic("res: resource type set multiple times") } hs.Type = TypeModel }) // Collection sets handler type to collection Collection = OptionFunc(func(hs *Handler) { if hs.Type != TypeUnset { panic("res: resource type set multiple times") } hs.Type = TypeCollection }) )
var DeleteAction = &struct{ json.RawMessage }{RawMessage: json.RawMessage(`{"action":"delete"}`)}
DeleteAction is used for deleted properties in "change" events
Functions ¶
This section is empty.
Types ¶
type AccessHandler ¶
type AccessHandler func(AccessRequest)
AccessHandler is a function called on resource access requests
var ( // AccessGranted is an access handler that provides full get and call access. AccessGranted AccessHandler = func(r AccessRequest) { r.AccessGranted() } // AccessDenied is an access handler that sends a response denying all access. AccessDenied AccessHandler = func(r AccessRequest) { r.AccessDenied() } )
Predefined handlers
type AccessRequest ¶
type AccessRequest interface { Resource Access(get bool, call string) AccessDenied() AccessGranted() NotFound() InvalidQuery(message string) Error(err error) Timeout(d time.Duration) }
AccessRequest has methods for responding to access requests.
type ApplyAddHandler ¶ added in v0.3.2
ApplyAddHandler is a function called to apply a collection add event. Must return an error if the add event couldn't be applied to the resource.
type ApplyChangeHandler ¶ added in v0.3.2
type ApplyChangeHandler func(r Resource, changes map[string]interface{}) (map[string]interface{}, error)
ApplyChangeHandler is a function called to apply a model change event. Must return a map with the values to apply to revert the changes, or error.
type ApplyCreateHandler ¶ added in v0.3.2
ApplyCreateHandler is a function called to apply a resource create event. Must return an error if the resource couldn't be created.
type ApplyDeleteHandler ¶ added in v0.3.2
ApplyDeleteHandler is a function called to apply a resource delete event. Must return the resource data being removed, or error.
type ApplyRemoveHandler ¶ added in v0.3.2
ApplyRemoveHandler is a function called to apply a collection remove event. Must return the value being removed, or error.
type AuthHandler ¶
type AuthHandler func(AuthRequest)
AuthHandler is a function called on resource auth requests
type AuthRequest ¶
type AuthRequest interface { Resource Method() string RawParams() json.RawMessage ParseParams(interface{}) Header() map[string][]string Host() string RemoteAddr() string URI() string OK(result interface{}) Resource(rid string) NotFound() MethodNotFound() InvalidParams(message string) InvalidQuery(message string) Error(err error) Timeout(d time.Duration) TokenEvent(t interface{}) }
AuthRequest has methods for responding to auth requests.
type CallHandler ¶
type CallHandler func(CallRequest)
CallHandler is a function called on resource call requests
type CallRequest ¶
type CallRequest interface { Resource Method() string RawParams() json.RawMessage ParseParams(interface{}) OK(result interface{}) Resource(rid string) NotFound() MethodNotFound() InvalidParams(message string) InvalidQuery(message string) Error(err error) Timeout(d time.Duration) }
CallRequest has methods for responding to call requests.
type CollectionHandler ¶
type CollectionHandler func(CollectionRequest)
CollectionHandler is a function called on collection get requests
type CollectionRequest ¶
type CollectionRequest interface { Resource Collection(collection interface{}) QueryCollection(collection interface{}, query string) NotFound() InvalidQuery(message string) Error(err error) Timeout(d time.Duration) ForValue() bool }
CollectionRequest has methods for responding to collection get requests.
type Conn ¶
type Conn interface { // Publish publishes the data argument to the given subject Publish(subject string, payload []byte) error // ChanSubscribe subscribes to messages matching the subject pattern. ChanSubscribe(subject string, ch chan *nats.Msg) (*nats.Subscription, error) // QueueSubscribeSyncWithChan subscribes to messages matching the subject pattern. QueueSubscribeSyncWithChan(subj, queue string, ch chan *nats.Msg) (*nats.Subscription, error) // Close will close the connection to the server. Close() }
Conn is an interface that represents a connection to a NATS server. It is implemented by nats.Conn.
type Error ¶
type Error struct { Code string `json:"code"` Message string `json:"message"` Data interface{} `json:"data,omitempty"` }
Error represents an RES error
func InternalError ¶
InternalError converts an error to an *Error with the code system.internalError.
type Event ¶ added in v0.3.2
type Event struct { // Name of the event. Name string // Resource emitting the event. Resource Resource // New property values for the model emitting the event. // * Only valid for "change" events. NewValues map[string]interface{} // Old property values for the model emitting the event. // * Only valid for "change" events. // * Value will be Delete for new properties. OldValues map[string]interface{} // Value being added or removed from // the collection emitting the event. // * Only valid for "add" and "remove" events. // * Only set for "remove" events if an ApplyRemove handler is defined. Value interface{} // Index position where the value is added or removed from // the collection emitting the event. // * Only valid for "add" and "remove" events. Idx int // Data for the created or deleted resource. // * Only valid for "create" and "delete" events. // * Only set for "delete" events if an ApplyDelete handler is defined. Data interface{} // Payload of a custom event. Payload interface{} }
Event represents an event emitted by resource.
type GetHandler ¶ added in v0.3.2
type GetHandler func(GetRequest)
GetHandler is a function called on untyped get requests
type GetRequest ¶ added in v0.3.2
type GetRequest interface { Resource Model(model interface{}) QueryModel(model interface{}, query string) Collection(collection interface{}) QueryCollection(collection interface{}, query string) NotFound() InvalidQuery(message string) Error(err error) Timeout(d time.Duration) ForValue() bool }
GetRequest has methods for responding to resource get requests.
type Handler ¶
type Handler struct { // Resource type Type ResourceType // Access handler for access requests Access AccessHandler // Get handler for get requests. Get GetHandler // Call handlers for call requests Call map[string]CallHandler // New handler for new call requests // // Deprecated: Use Call with Resource response instead; deprecated in RES // protocol v1.2.0 New NewHandler // Auth handler for auth requests Auth map[string]AuthHandler // ApplyChange handler for applying change event mutations ApplyChange ApplyChangeHandler // ApplyAdd handler for applying add event mutations ApplyAdd ApplyAddHandler // ApplyRemove handler for applying remove event mutations ApplyRemove ApplyRemoveHandler // ApplyCreate handler for applying create event ApplyCreate ApplyCreateHandler // ApplyDelete handler for applying delete event ApplyDelete ApplyDeleteHandler // Group is the identifier of the group the resource belongs to. All // resources of the same group will be handled on the same goroutine. The // group may contain tags, ${tagName}, where the tag name matches a // parameter placeholder name in the resource pattern. If empty, the // resource name will be used as identifier. Group string // OnRegister is callback that is to be call when the handler has been // registered to a service. // // The pattern is the full resource pattern for the resource, including any // service name or mount paths. // // The handler is the handler being registered, and should be considered // immutable. OnRegister func(service *Service, pattern Pattern, rh Handler) // Listeners is a map of event listeners, where the key is the resource // pattern being listened on, and the value being the callback called on // events. // // The callback will be called in the context of the resource emitting the // event. Listeners map[string]func(*Event) }
Handler contains handler functions for a given resource pattern.
type Match ¶ added in v0.3.2
type Match struct { Handler Handler Listeners []func(*Event) Params map[string]string Group string }
Match is a handler matching a resource name.
type ModelHandler ¶
type ModelHandler func(ModelRequest)
ModelHandler is a function called on model get requests
type ModelRequest ¶
type ModelRequest interface { Resource Model(model interface{}) QueryModel(model interface{}, query string) NotFound() InvalidQuery(message string) Error(err error) Timeout(d time.Duration) ForValue() bool }
ModelRequest has methods for responding to model get requests.
type Mux ¶ added in v0.3.2
type Mux struct {
// contains filtered or unexported fields
}
Mux stores handlers and efficiently retrieves them for resource names matching a pattern.
func NewMux ¶ added in v0.3.2
NewMux returns a new root Mux starting with given resource name path. Use an empty path to not add any prefix to the resource names.
func (*Mux) AddHandler ¶ added in v0.3.2
AddHandler register a handler for the given resource pattern. The pattern used is the same as described for Handle.
func (*Mux) AddListener ¶ added in v0.3.2
AddListener adds a listener for events that occurs on resources matching the exact pattern.
func (*Mux) Contains ¶ added in v0.3.2
Contains traverses through the registered handlers to see if any of them matches the predicate test.
func (*Mux) FullPath ¶ added in v0.3.2
FullPath returns the path that prefix all resource handlers, including the pattern derived from being mounted.
func (*Mux) GetHandler ¶ added in v0.3.2
GetHandler parses the resource name and gets the registered handler, event listeners, path params, and group ID. Returns the matching handler, or nil if not found.
func (*Mux) Handle ¶ added in v0.3.2
Handle registers the handler functions for the given resource pattern.
A pattern may contain placeholders that acts as wildcards, and will be parsed and stored in the request.PathParams map. A placeholder is a resource name part starting with a dollar ($) character:
s.Handle("user.$id", handler) // Will match "user.10", "user.foo", etc.
An anonymous placeholder is a resource name part using an asterisk (*) character:
s.Handle("user.*", handler) // Will match "user.10", "user.foo", etc.
A full wildcard can be used as last part using a greather than (>) character:
s.Handle("data.>", handler) // Will match "data.foo", "data.foo.bar", etc.
If the pattern is already registered, or if there are conflicts among the handlers, Handle panics.
func (*Mux) Mount ¶ added in v0.3.2
Mount attaches another Mux at a given path. When mounting, any path set on the sub Mux will be suffixed to the path.
func (*Mux) Path ¶ added in v0.3.2
Path returns the path that prefix all resource handlers, not including the pattern derived from being mounted.
func (*Mux) Register ¶ added in v0.3.2
Register registers the mux to a service. Will panic if already registered, or mounted to another mux.
func (*Mux) ValidateListeners ¶ added in v0.3.2
ValidateListeners validates that all patterns with event listeners has registered handlers, or panics if a handler is missing.
type NewHandler
deprecated
type NewHandler func(NewRequest)
NewHandler is a function called on new resource call requests
Deprecated: Use CallHandler with Resource response instead; deprecated in RES protocol v1.2.0
type NewRequest ¶
type NewRequest interface { Resource RawParams() json.RawMessage ParseParams(interface{}) New(rid Ref) NotFound() MethodNotFound() InvalidParams(message string) InvalidQuery(message string) Error(err error) Timeout(d time.Duration) }
NewRequest has methods for responding to new call requests.
type Option ¶ added in v0.3.2
type Option interface{ SetOption(*Handler) }
Option set one or more of the handler functions for a resource Handler.
func Access ¶
func Access(h AccessHandler) Option
Access sets a handler for resource access requests.
func ApplyAdd ¶ added in v0.3.2
func ApplyAdd(h ApplyAddHandler) Option
ApplyAdd sets a handler for applying add events.
func ApplyChange ¶ added in v0.3.2
func ApplyChange(h ApplyChangeHandler) Option
ApplyChange sets a handler for applying change events.
func ApplyCreate ¶ added in v0.3.2
func ApplyCreate(h ApplyCreateHandler) Option
ApplyCreate sets a handler for applying create events.
func ApplyDelete ¶ added in v0.3.2
func ApplyDelete(h ApplyDeleteHandler) Option
ApplyDelete sets a handler for applying delete events.
func ApplyRemove ¶ added in v0.3.2
func ApplyRemove(h ApplyRemoveHandler) Option
ApplyRemove sets a handler for applying remove events.
func Auth ¶
func Auth(method string, h AuthHandler) Option
Auth sets a handler for resource auth requests.
func Call ¶
func Call(method string, h CallHandler) Option
Call sets a handler for resource call requests.
Panics if the method is the pre-defined call method set.
For pre-defined set call methods, the handler Set should be used instead.
func GetCollection ¶
func GetCollection(h CollectionHandler) Option
GetCollection sets a handler for collection get requests.
func GetModel ¶
func GetModel(h ModelHandler) Option
GetModel sets a handler for model get requests.
func GetResource ¶ added in v0.3.2
func GetResource(h GetHandler) Option
GetResource sets a handler for untyped resource get requests.
func Group ¶ added in v0.3.2
Group sets a group ID. All resources of the same group will be handled on the same goroutine.
The group may contain tags, ${tagName}, where the tag name matches a parameter placeholder name in the resource pattern.
func New
deprecated
func New(h NewHandler) Option
New sets a handler for new resource requests.
Deprecated: Use Call with Resource response instead; deprecated in RES protocol v1.2.0
func OnRegister ¶ added in v0.3.2
OnRegister sets a callback to be called when the handler is registered to a service.
If a callback is already registered, the new callback will be called after the previous one.
func Set ¶
func Set(h CallHandler) Option
Set sets a handler for set resource requests.
Is a n alias for Call("set", h)
type OptionFunc ¶ added in v0.3.2
type OptionFunc func(*Handler)
The OptionFunc type is an adapter to allow the use of ordinary functions as options. If f is a function with the appropriate signature, OptionFunc(f) is an Option that calls f.
func (OptionFunc) SetOption ¶ added in v0.3.2
func (f OptionFunc) SetOption(hs *Handler)
SetOption calls f(hs)
type Pattern ¶ added in v0.3.2
type Pattern string
Pattern is a resource pattern that may contain wildcards and tags.
Pattern("example.resource.>") // Full wild card (>) matches anything that follows Pattern("example.item.*") // Wild card (*) matches a single part Pattern("example.model.$id") // Tag (starting with $) matches a single part
func (Pattern) IndexWildcard ¶ added in v0.3.2
IndexWildcard returns the index of the first instance of a wild card (*, >, or $tag) in pattern, or -1 if no wildcard is present.
Behavior is undefined for an invalid pattern.
func (Pattern) IsValid ¶ added in v0.3.2
IsValid returns true if the pattern is valid, otherwise false.
func (Pattern) Matches ¶ added in v0.3.2
Matches tests if the resource name, s, matches the pattern.
The resource name might in itself contain wild cards and tags.
Behavior is undefined for an invalid pattern or an invalid resource name.
func (Pattern) ReplaceTag ¶ added in v0.3.2
ReplaceTag searches for a given tag (without $) and replaces it with the value.
Behavior is undefined for an invalid pattern.
func (Pattern) ReplaceTags ¶ added in v0.3.2
ReplaceTags searches for tags and replaces them with the map value for the key matching the tag (without $).
Behavior is undefined for an invalid pattern.
type QueryRequest ¶ added in v0.3.2
type QueryRequest interface { Resource Model(model interface{}) Collection(collection interface{}) NotFound() InvalidQuery(message string) Error(err error) Timeout(d time.Duration) }
QueryRequest has methods for responding to query requests.
type Ref ¶
type Ref string
Ref is a resource reference to another resource ID. It marshals into a reference object, eg.:
{"rid":"userService.user.42"}
func (Ref) MarshalJSON ¶
MarshalJSON makes Ref implement the json.Marshaler interface.
func (*Ref) UnmarshalJSON ¶ added in v0.3.2
UnmarshalJSON makes Ref implement the json.Unmarshaler interface.
type Request ¶
type Request struct {
// contains filtered or unexported fields
}
Request represent a RES request
func (*Request) Access ¶
Access sends a successful response.
The get flag tells if the client has access to get (read) the resource. The call string is a comma separated list of methods that the client can call. Eg. "set,foo,bar". A single asterisk character ("*") means the client is allowed to call any method. Empty string means no calls are allowed.
Only valid for access requests.
func (*Request) AccessDenied ¶
func (r *Request) AccessDenied()
AccessDenied sends a system.accessDenied response.
Only valid for access requests.
func (*Request) AccessGranted ¶
func (r *Request) AccessGranted()
AccessGranted a successful response granting full access to the resource. Same as calling:
Access(true, "*");
Only valid for access requests.
func (*Request) AddEvent ¶
func (r *Request) AddEvent(v interface{}, idx int)
AddEvent sends an add event, adding the value v at index idx.
Only valid for a collection resource.
func (*Request) CID ¶
func (r *Request) CID() string
CID returns the connection ID of the requesting client connection. Empty string for get requests.
func (*Request) ChangeEvent ¶
func (r *Request) ChangeEvent(changed map[string]interface{})
ChangeEvent sends a change event. The changed map's keys are the key names for the model properties, and the values are the new values. If changed is empty, no event is sent.
Only valid for a model resource.
func (*Request) Collection ¶
func (r *Request) Collection(collection interface{})
Collection sends a successful collection response for the get request. The collection must marshal into a JSON array.
Only valid for get requests for a collection resource.
func (*Request) CreateEvent ¶ added in v0.3.2
func (r *Request) CreateEvent(data interface{})
CreateEvent sends a create event for the resource, where data is the created resource data.
func (*Request) DeleteEvent ¶ added in v0.3.2
func (r *Request) DeleteEvent()
DeleteEvent sends a delete event.
func (*Request) Event ¶
func (r *Request) Event(event string, payload interface{})
Event sends a custom event on the resource. Will panic if the event is one of the pre-defined or reserved events, "change", "delete", "add", "remove", "patch", "reaccess", "unsubscribe", or "query". For pre-defined events, the matching method, ChangeEvent, AddEvent, RemoveEvent, CreateEvent, DeleteEvent, or ReaccessEvent should be used instead.
This is to ensure compliance with the specifications: https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#events
func (*Request) ForValue ¶ added in v0.3.2
ForValue is used to tell whether a get request handler is called as a result of Value being called from another handler.
Only valid for get requests.
func (*Request) Group ¶ added in v0.3.2
func (r *Request) Group() string
Group returns the group which the resource shares the worker goroutine with. Will be the resource name of no specific group was set.
func (*Request) Header ¶
Header returns the HTTP headers sent by client on connect.
Only set for auth requests.
func (*Request) Host ¶
Host returns the host on which the URL is sought by the client. Per RFC 2616, this is either the value of the "Host" header or the host name given in the URL itself.
Only set for auth requests.
func (*Request) InvalidParams ¶
InvalidParams sends a system.invalidParams response. An empty message will default to "Invalid parameters".
Only valid for call and auth requests.
func (*Request) InvalidQuery ¶ added in v0.3.2
InvalidQuery sends a system.invalidQuery response. An empty message will default to "Invalid query".
func (*Request) Method ¶
Method returns the resource method. Empty string for access and get requests.
func (*Request) MethodNotFound ¶
func (r *Request) MethodNotFound()
MethodNotFound sends a system.methodNotFound response for the request.
Only valid for call and auth requests.
func (*Request) Model ¶
func (r *Request) Model(model interface{})
Model sends a successful model response for the get request. The model must marshal into a JSON object.
Only valid for get requests for a model resource.
func (*Request) NotFound ¶
func (r *Request) NotFound()
NotFound sends a system.notFound response for the request.
func (*Request) OK ¶
func (r *Request) OK(result interface{})
OK sends a successful result response to a request. The result may be nil.
Only valid for call and auth requests.
func (*Request) ParseParams ¶
func (r *Request) ParseParams(p interface{})
ParseParams unmarshals the JSON encoded parameters and stores the result in p. If the request has no parameters, ParseParams does nothing. On any error, ParseParams panics with a system.invalidParams *Error.
Only valid for call and auth requests.
func (*Request) ParseQuery ¶
ParseQuery parses the query and returns the corresponding values. It silently discards malformed value pairs. To check errors use url.ParseQuery.
func (*Request) ParseToken ¶
func (r *Request) ParseToken(t interface{})
ParseToken unmarshals the JSON encoded token and stores the result in t. If the request has no token, ParseToken does nothing. On any error, ParseToken panics with a system.internalError *Error.
func (*Request) PathParam ¶
PathParam returns the parameter derived from the resource name for the key placeholder.
func (*Request) PathParams ¶
PathParams returns parameters that are derived from the resource name.
func (*Request) Query ¶
func (r *Request) Query() string
Query returns the query part of the resource ID without the question mark separator.
func (*Request) QueryCollection ¶
QueryCollection sends a successful query collection response for the get request. The collection must marshal into a JSON array.
Only valid for get requests for a collection query resource.
func (*Request) QueryEvent ¶ added in v0.3.2
func (r *Request) QueryEvent(cb func(QueryRequest))
QueryEvent sends a query event on the resource, calling the provided callback on any query request. The last call to the callback will always be with nil, indicating that the query event duration has expired.
func (*Request) QueryModel ¶
QueryModel sends a successful query model response for the get request. The model must marshal into a JSON object.
Only valid for get requests for a model query resource.
func (*Request) RawParams ¶
func (r *Request) RawParams() json.RawMessage
RawParams returns the JSON encoded method parameters, or nil if the request had no parameters. Always returns nil for access and get requests.
func (*Request) RawToken ¶
func (r *Request) RawToken() json.RawMessage
RawToken returns the JSON encoded access token, or nil if the request had no token. Always returns nil for get requests.
func (*Request) ReaccessEvent ¶
func (r *Request) ReaccessEvent()
ReaccessEvent sends a reaccess event.
func (*Request) RemoteAddr ¶
RemoteAddr returns the network address of the client sent on connect. The format is not specified.
Only set for auth requests.
func (*Request) RemoveEvent ¶
func (r *Request) RemoveEvent(idx int)
RemoveEvent sends an remove event, removing the value at index idx.
Only valid for a collection resource.
func (*Request) RequireValue ¶ added in v0.3.2
func (r *Request) RequireValue() interface{}
RequireValue uses Value to gets the resource value, provided from the Get resource handler. It panics if the underlying call to Value return an error.
func (*Request) ResetEvent ¶ added in v0.3.2
func (r *Request) ResetEvent()
ResetEvent sends a system.reset event for the specific resource.
func (*Request) Resource ¶ added in v0.3.2
Resource sends a successful resource response to a request. The rid string must be a valid resource ID.
Only valid for call and auth requests.
func (*Request) ResourceName ¶
func (r *Request) ResourceName() string
ResourceName returns the resource name.
func (*Request) ResourceType ¶ added in v0.3.2
func (r *Request) ResourceType() ResourceType
ResourceType returns the resource type.
func (*Request) Timeout ¶
Timeout attempts to set the timeout duration of the request. The call has no effect if the requester has already timed out the request.
func (*Request) TokenEvent ¶
func (r *Request) TokenEvent(token interface{})
TokenEvent sends a connection token event that sets the requester's connection access token, discarding any previously set token. A change of token will invalidate any previous access response received using the old token. A nil token clears any previously set token. To set the connection token for a different connection ID, use Service.TokenEvent.
Only valid for auth requests.
func (*Request) URI ¶
URI returns the unmodified Request-URI of the Request-Line (RFC 2616, Section 5.1) as sent by the client on connect.
Only set for auth requests.
type Resource ¶
type Resource interface { // Service returns the service instance Service() *Service // Resource returns the resource name. ResourceName() string // ResourceType returns the resource type. ResourceType() ResourceType // PathParams returns parameters that are derived from the resource name. PathParams() map[string]string // PathParam returns the key placeholder parameter value derived from the resource name. PathParam(string) string // CID returns the Connection Identifier CID() string // RawToken returns the token serialized RawToken() json.RawMessage // ParseToken parses the token on provided interface ParseToken(interface{}) // Query returns the query part of the resource ID without the question mark separator. Query() string // Group which the resource shares worker goroutine with. // Will be the resource name of no specific group was set. Group() string // ParseQuery parses the query and returns the corresponding values. // It silently discards malformed value pairs. // To check errors use url.ParseQuery(Query()). ParseQuery() url.Values // Value gets the resource value as provided from the Get resource handlers. // If it fails to get the resource value, or no get handler is // defined, it returns a nil interface and a *Error type error. Value() (interface{}, error) // RequireValue gets the resource value as provided from the Get resource handlers. // Panics if it fails to get the resource value, or no get handler is defined. RequireValue() interface{} // Event sends a custom event on the resource. // Will panic if the event is one of the pre-defined or reserved events, // "change", "delete", "add", "remove", "patch", "reaccess", "unsubscribe", or "query". // For pre-defined events, the matching method, ChangeEvent, AddEvent, // RemoveEvent, CreateEvent, DeleteEvent, or ReaccessEvent should be used instead. // // This is to ensure compliance with the specifications: // https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#events Event(event string, payload interface{}) // ChangeEvents sends a change event with properties that has been changed // and their new values. // If props is empty, no event is sent. // Panics if the resource is not a Model. // The values must be serializable into JSON primitives, resource references, // or a delete action objects. // See the protocol specification for more information: // https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#model-change-event ChangeEvent(props map[string]interface{}) // AddEvent sends an add event, adding the value at index idx. // Panics if the resource is not a Collection, or if idx is less than 0. // The value must be serializable into a JSON primitive or resource reference. // See the protocol specification for more information: // https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#collection-add-event AddEvent(value interface{}, idx int) // RemoveEvent sends a remove event, removing the value at index idx. // Panics if the resource is not a Collection, or if idx is less than 0. // See the protocol specification for more information: // https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#collection-remove-event RemoveEvent(idx int) // ReaccessEvent sends a reaccess event to signal that the resource's access permissions has changed. // It will invalidate any previous access response sent for the resource. // See the protocol specification for more information: // https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#reaccess-event ReaccessEvent() // ResetEvent sends a reset event to signal that the resource's data has changed. // It will invalidate any previous get response sent for the resource. // See the protocol specification for more information: // https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#reaccess-event ResetEvent() // QueryEvent sends a query event to signal that the query resource's underlying data has been modified. // See the protocol specification for more information: // https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#query-event QueryEvent(func(QueryRequest)) // CreateEvent sends a create event, to signal the resource has been created, with // value being the resource value. CreateEvent(value interface{}) // DeleteEvent sends a delete event, to signal the resource has been deleted. DeleteEvent() }
Resource represents a resource
type ResourceType ¶ added in v0.3.2
type ResourceType byte
ResourceType enum
const ( TypeUnset ResourceType = iota TypeModel TypeCollection )
Resource type enum values
type Service ¶
type Service struct { *Mux // contains filtered or unexported fields }
A Service handles incoming requests from NATS Server and calls the appropriate callback on the resource handlers.
func NewService ¶
NewService creates a new Service.
The name is the service name which will be prefixed to all resources. It must be an alphanumeric string with no embedded whitespace, or empty. If name is an empty string, the Service will by default handle all resources for all namespaces. Use SetReset to limit the namespace scope.
func (*Service) ListenAndServe ¶
ListenAndServe connects to the NATS server at the url. Once connected, it subscribes to incoming requests and serves them on a single goroutine in the order they are received. For each request, it calls the appropriate handler, or replies with the appropriate error if no handler is available.
In case of disconnect, it will try to reconnect until Close is called, or until successfully reconnecting, upon which Reset will be called.
ListenAndServe returns an error if failes to connect or subscribe. Otherwise, nil is returned once the connection is closed using Close.
func (*Service) ProtocolVersion ¶ added in v0.3.2
ProtocolVersion returns the supported RES protocol version.
func (*Service) Reset ¶ added in v0.3.2
Reset sends a system reset for the provided resource patterns.
func (*Service) ResetAll ¶
func (s *Service) ResetAll()
ResetAll will send a system.reset to trigger any gateway to update their cache for all resources handled by the service.
The method is automatically called on server start and reconnects.
func (*Service) Resource ¶ added in v0.3.2
Resource matches the resource ID, rid, with the registered Handlers and returns the resource, or an error if there is no matching handler found.
Should only be called from within the resource's group goroutine. Using the returned value from another goroutine may cause race conditions.
func (*Service) Serve ¶
Serve subscribes to incoming requests on the *Conn nc, serving them on a single goroutine in the order they are received. For each request, it calls the appropriate handler, or replies with the appropriate error if no handler is available.
Serve returns an error if failes to subscribe. Otherwise, nil is returned once the *Conn is closed.
func (*Service) SetOnDisconnect ¶ added in v0.3.2
SetOnDisconnect sets a function to call when the service has been disconnected from NATS server.
func (*Service) SetOnError ¶ added in v0.3.2
SetOnError sets a function to call on errors within the service, or incoming messages not complying with the RES protocol.
func (*Service) SetOnReconnect ¶ added in v0.3.2
SetOnReconnect sets a function to call when the service has reconnected to NATS server and sent a system reset event.
func (*Service) SetOnServe ¶ added in v0.3.2
SetOnServe sets a function to call when the service has started after sending the initial system reset event.
func (*Service) SetOwnedResources ¶ added in v0.3.2
SetOwnedResources sets the patterns which the service will handle requests for. The resources slice patterns ill be listened to for get, call, and auth requests. The access slice patterns will be listened to for access requests. These patterns will be used when a ResetAll is made.
// Handle all requests for resources prefixed "library." service.SetOwnedResources([]string{"library.>"}, []string{"library.>"}) // Handle access requests for any resource service.SetOwnedResources([]string{}, []string{">"}) // Handle non-access requests for a subset of resources service.SetOwnedResources([]string{"library.book", "library.books.*"}, []string{})
If set to nil (default), the service will default to set ownership of all resources prefixed with its own path if one was provided when creating the service (eg. "serviceName.>"), or to all resources if no name was provided. It will take resource ownership if it has at least one registered handler has a Get, Call, or Auth handler method not being nil. It will take access ownership if it has at least one registered handler with the Access method not being nil.
For more details on system reset, see: https://github.com/resgateio/resgate/blob/master/docs/res-service-protocol.md#system-reset-event
func (*Service) SetQueryEventDuration ¶ added in v0.3.2
SetQueryEventDuration sets the duration for which the service will listen for query requests sent on a query event. Default is 3 seconds
func (*Service) Shutdown ¶
Shutdown closes any existing connection to NATS Server. Returns an error if service is not started.
func (*Service) TokenEvent ¶
TokenEvent sends a connection token event that sets the connection's access token, discarding any previously set token.
A change of token will invalidate any previous access response received using the old token.
A nil token clears any previously set token.
func (*Service) With ¶
With matches the resource ID, rid, with the registered Handlers before calling the callback, cb, on the worker goroutine for the resource name or group.
With will return an error and not call the callback if there is no matching handler found.
func (*Service) WithGroup ¶ added in v0.3.2
WithGroup calls the callback, cb, on the group's worker goroutine.
func (*Service) WithResource ¶ added in v0.3.2
WithResource enqueues the callback, cb, to be called by the resource's worker goroutine. If the resource belongs to a group, it will be called on the group's worker goroutine.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
examples
|
|
02-edit-text
This is an example of a simple text field that can be edited by multiple clients.
|
This is an example of a simple text field that can be edited by multiple clients. |
03-book-collection
This is an example RES service that shows a lists of books, where book titles can be added, edited and deleted by multiple users simultaneously.
|
This is an example RES service that shows a lists of books, where book titles can be added, edited and deleted by multiple users simultaneously. |
04-book-collection-store
This is the Book Collection example where all changes are persisted using a badgerDB store.
|
This is the Book Collection example where all changes are persisted using a badgerDB store. |
05-search-query
A customer management system, where you can search and filter customers by name and country.
|
A customer management system, where you can search and filter customers by name and country. |
Package middleware provides middleware for the res package: https://github.com/jirenius/go-res Middleware can be used for adding handler functions to a res.Handler, to perform tasks such as: * storing, loading and updating persisted data * synchronize changes between multiple service instances * add additional logging * provide helpers for complex live queries Currently, only the BadgerDB middleware is created, to demonstrate database persistence.
|
Package middleware provides middleware for the res package: https://github.com/jirenius/go-res Middleware can be used for adding handler functions to a res.Handler, to perform tasks such as: * storing, loading and updating persisted data * synchronize changes between multiple service instances * add additional logging * provide helpers for complex live queries Currently, only the BadgerDB middleware is created, to demonstrate database persistence. |
Package restest provides utilities for testing res services: Usage func TestService(t *testing.T) { // Create service to test s := res.NewService("foo") s.Handle("bar.$id", res.Access(res.AccessGranted), res.GetModel(func(r res.ModelRequest) { r.Model(struct { Message string `json:"msg"` }{r.PathParam("id")}) }), ) // Create test session c := restest.NewSession(t, s) defer c.Close() // Test sending get request and validate response c.Get("foo.bar.42").
|
Package restest provides utilities for testing res services: Usage func TestService(t *testing.T) { // Create service to test s := res.NewService("foo") s.Handle("bar.$id", res.Access(res.AccessGranted), res.GetModel(func(r res.ModelRequest) { r.Model(struct { Message string `json:"msg"` }{r.PathParam("id")}) }), ) // Create test session c := restest.NewSession(t, s) defer c.Close() // Test sending get request and validate response c.Get("foo.bar.42"). |