@hitchy/plugin-odem-socket.io

0.2.3 • Public • Published

@hitchy/plugin-odem-socket.io

exposing Hitchy's ODM via websocket

License

MIT

Installation

npm i @hitchy/plugin-odem-socket.io

This plugin relies on additional plugins to be installed as well:

npm i @hitchy/plugin-odem @hitchy/plugin-socket.io

Breaking changes

v0.2

  • The parameter uuidsOnly of actions <modelName>:list and <modelName>:find has been replaced by loadRecords to match the semantics of server-side Odem API. You have to negate its value to adapt.

Usage

Basics

This plugin is establishing an API via websocket for controlling and monitoring models of server-side ODM. 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 <modelName> is used instead of that kebab-case variant of a model's name.

Control API

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:

const socket = io( "/hitchy/odem" );

socket.on( "connect", () => {
    socket.emit( actionName, sessionId, arg1, arg2, arg3, response => {
        // process the response here
    } );
} );

socket.io requires all arguments to be provided no matter what. Thus, you can't 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.

In all these examples, a sessionId is given. This is the current user's session ID usually found in a cookie set by a preceding HTTP request to authenticate the user. It is required on all requests to re-authenticate the user and to apply authorization checks to either request. It is okay to provide null here, however this might cause requests to be rejected based on server-side configuration.

<modelName>:list

This request is the websocket variant of Model.list(). Supported arguments are

  • the session ID,

  • query-related options as supported by Model.list() and

  • a boolean controlling loadRecords of result-related options supported by Model.list().

    This boolean must be true to actually get all properties of retrieved items. Otherwise, listed items are represented by their UUIDs, only.

socket.emit( "<modelName>:list", sessionId, { limit: 10 }, false, response => {
    // - check for `response.success` or `response.error`
    // - process total count of items in `response.count`
    // - process requested excerpt of items in `response.items`
} );

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 session ID,

  • the query describing items to find,

  • query-related options as supported by Model.find() and

  • a boolean controlling loadRecords of result-related options supported by Model.find().

    This boolean must be true to actually get all properties of retrieved items. Otherwise, listed items are represented by their UUIDs, only.

socket.emit( "<modelName>:find", sessionId, {}, { limit: 10 }, true, response => {
    // - check for `response.success` or `response.error`
    // - process total count of items in `response.count`
    // - process requested excerpt of items in `response.items`
} );

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. Properties of instance to create are provided as serializable object in argument following the session ID.

socket.emit( "<modelName>:create", sessionId, { title: "important things" }, response => {
    // - check for `response.success` or `response.error`
    // - process properties of eventually created instance in `response.properties`
    // - created instance's UUID is available as `response.properties.uuid`
} );

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.

socket.emit( "<modelName>:read", sessionId, "12345678-1234-1234-1234-123456789012", response => {
    // - check for `response.success` or `response.error`
    // - process properties of fetched instance in `response.properties`
} );

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. Following the session ID, the UUID of item to update and the values per property to assign are provided in additional arguments.

socket.emit( "<modelName>:update", sessionId, "12345678-1234-1234-1234-123456789012", { prio: 1 }, response => {
    // - check for `response.success` or `response.error`
    // - properties of updated instance are provided in `response.properties`
} );

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.

socket.emit( "<modelName>:delete", sessionId, "12345678-1234-1234-1234-123456789012", response => {
    // - check for `response.success` or `response.error`
    // - deleted instance's UUID is available as `response.properties.uuid`
} );

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

ODM notifications are forwarded as broadcast events named <modelName>:changed. 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,
  • updated on notifications about having adjusted one or more properties of an existing instance of model and
  • deleted on notifications about having removed an existing instance of model.

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:

const socket = io( "/hitchy/odem" );

socket.on( "<modelName>:changed", info => {
    // type of change is in `info.change`, e.g. "updated"
    // process properties of changed instance in `info.properties`
} );

There may be server-side restriction applying per event or per instance of model, thus some or all notifications might be omitted.

Readme

Keywords

Package Sidebar

Install

npm i @hitchy/plugin-odem-socket.io

Weekly Downloads

1

Version

0.2.3

License

MIT

Unpacked Size

25.9 kB

Total Files

7

Last publish

Collaborators

  • soletan
  • simon.friedo