Documentation ¶
Overview ¶
Package res is used to create REST, real time, and RPC APIs, where all your reactive web clients are synchronized seamlessly through Resgate:
https://github.com/resgateio/resgate
The implementation provides structs and methods for creating services that listen to requests and send events over NATS server.
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
- func IsValidRID(rid string) bool
- 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 DataValue
- 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) Conn() Conn
- 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(conn Conn) error
- func (s *Service) SetInChannelSize(size int) *Service
- 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) SetQueueGroup(queue string) *Service
- func (s *Service) SetReset(resources, access []string) *Servicedeprecated
- func (s *Service) SetWorkerCount(count int) *Service
- func (s *Service) Shutdown() error
- func (s *Service) TokenEvent(cid string, token interface{})
- func (s *Service) TokenEventWithID(cid string, tokenID string, token interface{})
- func (s *Service) TokenReset(subject string, tokenID ...string)
- 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())
- type SoftRef
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 ¶
func IsValidRID ¶ added in v0.4.0
IsValidRID returns true if the resource ID is valid, otherwise false.
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 CID() string RawToken() json.RawMessage ParseToken(interface{}) 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 ¶
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 ¶
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 ¶
ApplyCreateHandler is a function called to apply a resource create event. Must return an error if the resource couldn't be created.
type ApplyDeleteHandler ¶
ApplyDeleteHandler is a function called to apply a resource delete event. Must return the resource data being removed, or error.
type ApplyRemoveHandler ¶
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 CID() string RawParams() json.RawMessage RawToken() json.RawMessage ParseParams(interface{}) ParseToken(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 CID() string RawParams() json.RawMessage RawToken() json.RawMessage ParseParams(interface{}) ParseToken(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 // PublishRequest publishes a request expecting a response on the reply // subject. PublishRequest(subject, reply string, data []byte) error // ChanSubscribe subscribes to messages matching the subject pattern. ChanSubscribe(subject string, ch chan *nats.Msg) (*nats.Subscription, error) // ChanQueueSubscribe subscribes to messages matching the subject pattern. // All subscribers with the same queue name will form the queue group and // only one member of the group will be selected to receive any given // message, which will be placed on the channel. ChanQueueSubscribe(subject, 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 DataValue ¶ added in v0.4.0
type DataValue struct {
Data interface{} `json:"data"`
}
DataValue is a wrapper for values that may marshal into any type of json value, including objects, arrays, or nested structures.
If a value marshals into a json object or array, it must be wrapped with DataValue or similar, or else the value will be considered invalid.
Example:
s.Handle("timezones", res.GetCollection(func(r res.CollectionRequest) { type tz struct { Abbr string `json:"abbr"` Offset int `json:"offset"` } r.Collection([]res.DataValue{ res.DataValue{tz{"GMT", 0}}, res.DataValue{tz{"CET", 1}}, }) }))
For objects and arrays, it marshals into a data value object, eg.:
json.Marshal(res.DataValue{[]int{1, 2, 3}}) // Result: {"data":[1,2,3]}
For strings, numbers, booleans, and null values, it marshals into a primitive value, eg.:
json.Marshal(res.DataValue{nil}) // Result: null
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.2.0
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 ¶
type GetHandler func(GetRequest)
GetHandler is a function called on untyped get requests
type GetRequest ¶
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.2.0
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 ¶
type Mux struct {
// contains filtered or unexported fields
}
Mux stores handlers and efficiently retrieves them for resource names matching a pattern.
func NewMux ¶
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 ¶
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.2.0
AddListener adds a listener for events that occurs on resources matching the exact pattern.
func (*Mux) Contains ¶
Contains traverses through the registered handlers to see if any of them matches the predicate test.
func (*Mux) FullPath ¶
FullPath returns the path that prefix all resource handlers, including the pattern derived from being mounted.
func (*Mux) GetHandler ¶
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 ¶
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 ¶
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 ¶
Path returns the path that prefix all resource handlers, not including the pattern derived from being mounted.
func (*Mux) Register ¶ added in v0.2.0
Register registers the mux to a service. Will panic if already registered, or mounted to another mux.
func (*Mux) ValidateListeners ¶ added in v0.2.0
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 CID() string RawParams() json.RawMessage RawToken() json.RawMessage ParseParams(interface{}) ParseToken(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 ¶
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 ¶
func ApplyAdd(h ApplyAddHandler) Option
ApplyAdd sets a handler for applying add events.
func ApplyChange ¶
func ApplyChange(h ApplyChangeHandler) Option
ApplyChange sets a handler for applying change events.
func ApplyCreate ¶
func ApplyCreate(h ApplyCreateHandler) Option
ApplyCreate sets a handler for applying create events.
func ApplyDelete ¶
func ApplyDelete(h ApplyDeleteHandler) Option
ApplyDelete sets a handler for applying delete events.
func ApplyRemove ¶
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 ¶
func GetResource(h GetHandler) Option
GetResource sets a handler for untyped resource get requests.
func Group ¶
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.2.0
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 ¶
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.
type Pattern ¶ added in v0.2.0
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.2.0
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.2.0
IsValid returns true if the pattern is valid, otherwise false.
func (Pattern) Matches ¶ added in v0.2.0
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.0
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.0
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 ¶
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 ¶
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 ¶
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 ¶
func (r *Request) CreateEvent(data interface{})
CreateEvent sends a create event for the resource, where data is the created resource data.
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 ¶
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 ¶
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.2.0
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.
Not valid for get requests.
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 ¶
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 ¶
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.2.0
func (r *Request) ResetEvent()
ResetEvent sends a system.reset event for the specific resource.
func (*Request) Resource ¶ added in v0.2.0
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 ¶
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 // 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 ¶
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) Conn ¶ added in v0.4.0
Conn returns the connection instance used by the service.
If the service is not started, nil is returned.
If the service was started using ListenAndServe, the connection will be of type *nats.Conn:
nc := service.Conn().(*nats.Conn)
func (*Service) ListenAndServe ¶
ListenAndServe connects to the NATS server at the url. Once connected, it subscribes to incoming requests. 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.2.0
ProtocolVersion returns the supported RES protocol version.
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 ¶
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 starts serving incoming requests received on the connection conn. For each request, it calls the appropriate handler, or replies with the appropriate error if no handler is available.
If the connection conn is of type *nats.Conn, Service will call SetReconnectHandler, SetDisconnectHandler, and SetClosedHandler, replacing any existing event handlers.
In case of disconnect, it will try to reconnect until Close is called, or until successfully reconnecting, upon which Reset will be called.
Serve returns an error if failes to subscribe. Otherwise, nil is returned once the connection is closed.
func (*Service) SetInChannelSize ¶ added in v0.4.7
SetInChannelSize sets the size of the in channel receiving messages from NATS Server. Default is 1024.
If size is less or equal to zero, the default value is used.
func (*Service) SetOnDisconnect ¶
SetOnDisconnect sets a function to call when the service has been disconnected from NATS server.
func (*Service) SetOnError ¶
SetOnError sets a function to call on errors within the service, or incoming messages not complying with the RES protocol.
func (*Service) SetOnReconnect ¶
SetOnReconnect sets a function to call when the service has reconnected to NATS server and sent a system reset event.
func (*Service) SetOnServe ¶
SetOnServe sets a function to call when the service has started after sending the initial system reset event.
func (*Service) SetOwnedResources ¶
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 ¶
SetQueryEventDuration sets the duration for which the service will listen for query requests sent on a query event. Default is 3 seconds
func (*Service) SetQueueGroup ¶ added in v0.4.0
SetQueueGroup sets the queue group to use when subscribing to resources. By default it will be the same as the service name.
If queue is set to an empty string, the service will not belong to any queue group.
func (*Service) SetWorkerCount ¶ added in v0.4.7
SetWorkerCount sets the number of workers handling incoming requests. Default is 32 workers.
If count is less or equal to zero, the default value is used.
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) TokenEventWithID ¶ added in v0.4.5
TokenEventWithID sends a connection token event in the same way as TokenEvent, but includes a token ID (tid).
The token ID is a string that identifies the token, used when calling TokenReset to update or clear a token.
func (*Service) TokenReset ¶ added in v0.4.5
TokenReset sends a token reset event for the provided token IDs.
The subject string is a message subject that will receive auth requests for any connections with a token matching any of the token IDs.
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) WithResource ¶
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.
type SoftRef ¶ added in v0.4.0
type SoftRef string
SoftRef is a soft resource reference to another resource ID which will not automatically be followed by Resgate.
It marshals into a soft reference object, eg.:
{"rid":"userService.user.42","soft":true}
func (SoftRef) IsValid ¶ added in v0.4.0
IsValid returns true if the soft reference RID is valid, otherwise false.
func (SoftRef) MarshalJSON ¶ added in v0.4.0
MarshalJSON makes SoftRef implement the json.Marshaler interface.
func (*SoftRef) UnmarshalJSON ¶ added in v0.4.0
UnmarshalJSON makes SoftRef implement the json.Unmarshaler interface.
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:
|
Package middleware provides middleware for the res package: |
Package resprot provides low level structs and methods for communicating with services using the RES Service Protocol over NATS server.
|
Package resprot provides low level structs and methods for communicating with services using the RES Service Protocol over NATS server. |
Package restest provides utilities for testing res services:
|
Package restest provides utilities for testing res services: |