hapi-view-models

阅读时长 10 分钟读完

Role-filtered view model support for Hapi

hapi View Models

A plugin to provide a concept of 'view-models' to hapi.

Purpose

When rendering payloads from an API, we often want to provide different subsets (or supersets) of data to users with different roles, or scopes. By leveraging lodash.omit and server.decorate, we can contain the complexity of doing this as a fairly neat abstraction, reducing the overall complexity of payload modification and filtering, and keeping our controllers clean.

With hapi-view-models it is possible to render a variety of different versions of a single entity (payload) from a single endpoint.

Installing

Installing is done in the usual way

Usage

The vm reply helper allows you to render views of your data:

Where vm takes the KeyPairViewModel and filters the data inside response according to the user's scope. Response can be a single entity or an array of entities.

If you're returning a response envelope you can provide a path to the entity as a third argument to the vm reply helper.

-- -------------------- ---- -------
----- ---------------- - --------------
--------------
  ---
  ------- --------- ------ -
    -------------------------- -
      ------- -
        ----- -----
      -
    -- --------------
  -
--

Real World Example

Suppose we owned a cryptocurrency exchange. That's very 'of the moment', isn't it?

Lets say our wallet owner has a role of 'owner', and a visitor doesn't have this role.

We'd want to build a view model to render a wallet's data in a secure way. We declare a set of properties that are included in the payload for each role. Including a property in a role automatically excludes that data from all other roles.

Roles are defined by hapi in request.auth.credentials.scope and are controlled by your auth mechanism.

Our view model extends ViewModel and looks like this:

-- -------------------- ---- -------
----- - --------- - - ---------------------------

----- ---------------- ------- --------- -
    --- -------- -- -
      ------ -
        ------ -----------
      -
    -
-

And our handler would look something like this:

-- -------------------- ---- -------
----- - ------ - - ---------------------------
----- ---------------- - --------------------------------------

-- -------- --- ------ ---- ----
----------------------- --- -- -
  -------------------
--

-------- ------------- --------- -
  -- ------- ---- - --------- ---- ---- -------
  ----- ------- - -
    -------- --------
    ------- -------
  -
-

--------------
  ------- ------
  ----- --------------------
  -------- -------- --------- ------ -
    ----- ------- - -------------------------------------
    -------------------------- --------
  -
--

The rendered data would look something like this:

-- -------------------- ---- -------
-- -- --- ----- -------- --- ------
-
  -------- --------
  ------- -------
-

-- --- -- - ------- -------- --- ------
-
  ------- -------
-

Understanding get includes()

The getter method get includes() or just .includes as a property on your view model is a mapping of scope to an array of properties that are (deep) filtered from the resultant payload. This means we also support nesting!

This means you can do:

-- -------------------- ---- -------
----- ---- - -
  -- -
    ---- -----
  --
  -- -
    -- ------ ------
    -- -
      -- -----------
    -
  -
-

----- ------------- ------- --------- -
    --- -------- -- -
      ------ -
        ------ ------ -- ---- - --- --- -------- ---
        ------ ----- ---- -- ---- - --- --- -------- --- --- ---
        ------ --------- -- ------- ---- ----- --- --- --- - --- ---- --- --- -------- -- --- ---- -- ---- -- ------- -- -------
      -
    -
-

You'll notice something going on here with includes. Includes is an 'exclusive' mapping. This means that if you declare a property visible by a role, it is hidden for all other roles. This means that you can minimally hide role-sensitive data, without having to re-iterate yourself or risk the leak of private properties leaking through.

TL;DR: Once a property is declared as visible to a role, it is automatically invisible to all other roles.

Ideally your user should have all the roles it needs to see all the data it needs, but if you like, you can 're-declare' visibility as we have done in the ase of role2 above. A user wanting to see a can have roles role1, role2, or both. a (and as a result a.foo) isn't visible to any other roles.

Structure

The plugin exports two modules:

  • plugin which is the hapi plugin providing reply.vm()
  • ViewModel which is the base class your view models should extend.

The plugin uses a slightly stricter extension of standard-style

Contributing

To contribute to the plugin, fork it to your own github account, create a branch, make your changes, and submit a PR.

Note that Vendigo Finance Ltd requires that you include tests to cover your new code, along with your PR in order to get it merged.

To run our test suite:

HomePage

https://github.com/vendigo-group/hapi-view-models#readme

Repository

git+https://github.com/vendigo-group/hapi-view-models.git

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/60056c7581e8991b448e5f23

纠错
反馈