exposing Hitchy's document-oriented database via websocket
_exposing Hitchy's document-oriented database via websocket_
``bash`
npm i @hitchy/plugin-odem-socket.io
This plugin relies on additional plugins to be installed as well:
`bash`
npm i @hitchy/plugin-odem @hitchy/plugin-socket.io
* The parameter uuidsOnly of actions and has been replaced by loadRecords to match the semantics of server-side Odem API. You have to negate its value to adapt.
* This version is recognizing an existing authentication plugin and checks a user's authorization for accessing models and their properties based on authorization rules set on server.
* Previously, actions of control API required the provision of a session ID to read a requesting user from as first argument. This approach has been abandoned. All actions are automatically associated with the user which has been authenticated when the websocket connection has been established.
* Clients should drop and re-connect over websocket whenever authentication of a requesting user has changed.
This plugin is exposing an API via websocket for controlling and monitoring models of server-side document-oriented database. Relying on particular features of socket.io, this API is exposed in namespace /hitchy/odem.
For every server-side model, request listeners and/or notification broadcasters are set up. Either model's name is converted into its kebab-case variant and used as colon-separated prefix in event names emitted either by the server or by a client.
> In the following sections, the placeholder is used instead of that kebab-case variant of a model's name.
> Attention!
>
> As of v0.1.0, the control API is disabled by default due to the lack of having authorization checks implemented on server-side. You have to enable it explicitly by setting runtime configuration parameter config.socket.odem.crud which defaults to false.
All action events listed in this section are to be sent by a client. The server is setting up listeners and directly responds to either received event. Thus, the common pattern on client side looks like this:
`javascript
const socket = io( "/hitchy/odem" );
socket.on( "connect", () => {
socket.emit( actionName, arg1, arg2, arg3, response => {
// process the response here
} );
} );
`
> socket.io requires all arguments to be provided no matter what. Thus, you can not omit any of the arguments given in examples below but have to provide values assumed to be default, at least.
The following code excerpts are focusing on the inner part of emitting an action event and processing the response.
#### <modelName>:list
This request is the websocket variant of Model.list(). Supported arguments are
* query-related options as supported by Model.list() andloadRecords
* a boolean controlling of result-related options supported by Model.list().
> This boolean must be true to actually get the properties of retrieved items. Otherwise, listed items are represented by their UUIDs, only.
`javascriptresponse.success
socket.emit( "
// - check for or response.errorresponse.count
// - process total count of items in response.items
// - process requested excerpt of items in `
} );
Last argument is a callback to be invoked with the resulting response from server-side. response is an object consisting of truthy property success on success or error message in case of a failure. On success, property count is providing total count of matches and items is the list of matching items' properties.
#### <modelName>:find
This request is searching for instances of selected model matching some query. It is invoking Model.find(). Arguments are
* the query describing items to find,
* query-related options as supported by Model.find() andloadRecords
* a boolean controlling of result-related options supported by Model.find().
> This boolean must be true to actually get the properties of retrieved items. Otherwise, listed items are represented by their UUIDs, only.
`javascriptresponse.success
socket.emit( "
// - check for or response.errorresponse.count
// - process total count of items in response.items
// - process requested excerpt of items in `
} );
Last argument is a callback to be invoked with the resulting response from server-side. response is an object consisting of truthy property success on success or error message in case of a failure. On success, property count is providing total count of matches and items is the selected excerpt from that list of matching items' each given by its properties including its UUID.
#### <modelName>:create
This request is creating another instance of selected model assigning provided properties as initial values. Those properties are provided as serializable object.
`javascriptresponse.success
socket.emit( "
// - check for or response.errorresponse.properties
// - process properties of eventually created instance in response.properties.uuid
// - created instance's UUID is available as `
} );
Last argument is a callback to be invoked with the resulting response from server-side. response is an object consisting of truthy property success on success or error message in case of a failure. On success, properties of created instance are returned. These may be different from provided ones due to server-side constraints. The created item's UUID is added to that set of properties as uuid.
#### <modelName>:read
This request is fetching a single instance's properties.
`javascriptresponse.success
socket.emit( "
// - check for or response.errorresponse.properties
// - process properties of fetched instance in `
} );
Last argument is a callback to be invoked with the resulting response from server-side. response is an object consisting of truthy property success on success or error message in case of a failure. On success, properties of selected instance are returned.
#### <modelName>:update
This request is updating an existing instance of model. The UUID of item to update and the values per property to assign are provided as arguments.
`javascriptresponse.success
socket.emit( "
// - check for or response.errorresponse.properties
// - properties of updated instance are provided in `
} );
Last argument is a callback to be invoked with the resulting response from server-side. response is an object consisting of truthy property success on success or error message in case of a failure. On success, properties of updated instance are returned. These may be different from provided ones due to server-side constraints.
#### <modelName>:delete
This request is eventually completing the CRUD-support of this API by deleting an existing instance of model selected by its UUID in first argument.
`javascriptresponse.success
socket.emit( "
// - check for or response.errorresponse.properties.uuid
// - deleted instance's UUID is available as `
} );
Last argument is a callback to be invoked with the resulting response from server-side. response is an object consisting of truthy property success on success or error message in case of a failure. On success, properties of updated instance are returned.
notifications of the document-oriented database are forwarded as broadcast events named . Either event consists of
- a type of change and
- the changed item's properties (limited to its UUID on deletion).
The type of change is
* created on notifications about having created another instance of model,changed
* on notifications about having adjusted one or more properties of an existing instance of model andremoved
* on notifications about having removed an existing instance of model.
:::danger Breaking change
Notification types have changed in v0.5.0 from updated to changed and from deleted to removed to match names used on server side.
:::
In last case the provided set of properties is limited to the instance's UUID. The common pattern on client-side for listening to server-side notifications looks like this:
`javascript
const socket = io( "/hitchy/odem" );
socket.on( "
// type of change is in info.change, e.g. "created", "changed" or "removed"info.properties
// process properties of changed instance in ``
} );
> There may be server-side restriction applying per event or per instance of model, thus some or all notifications might be omitted.