Socket
Book a DemoInstallSign in
Socket

pronto-data-service

Package Overview
Dependencies
Maintainers
3
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pronto-data-service

A base Data Service with multiple DB backends and a GraphQL layer

0.0.8-somata-peer
latest
Source
npmnpm
Version published
Weekly downloads
0
Maintainers
3
Weekly downloads
 
Created
Source

data-service

A base Data Service with multiple DB backends and a GraphQL layer

Installation

$ npm install git+ssh://git@github.com/prontotype-us/data-service.git

Schema

Create a file schema.sch

TODO: Document schema syntax

Usage

A DataService is used like a regular Somata Service, with a slightly different set of arguments:

new DataService(service_name, db_options, custom_methods)

DataService = require 'data-service'

# Create a MongoDB data service with only generic methods
new DataService 'myproject:data', {
    type: 'mongo'
    config: db: 'myprojectdb'
}

# Create a LocalDB with a specific method
new DataService 'myproject:data', {}, {doSpecificThing}

Options

  • type: Supported types are mongo for MongoDB, and pg for Postgres. Leave blank for an in-memory DB.
  • config:
    • id_key: Default is always id (for MongoDB, IDs are coerced from _id).
    • Specific DB types might use extra config options:
      • db: Required for MongoDB and Postgres.
      • host: Optional for MongoDB and Postgres.
      • user: Optional for MongoDB and Postgres.
    • strict_auth: Optionally set authorization to default to Unauthorized without access rules

Database Types

  • MongoDb
  • PostgresDb
  • LocalDb: In memory database for quick testing
  • ServiceDb: Forwards methods to a service that follows the data service protocol
  • MultiDb: Combines multiple Dbs into one, each Db handling its own set of collections

Methods

The base database exposes the following functions, all requiring a type argument (the collection name, e.g. "users"):

  • get(type, query)Item
  • find(type, query, search, options){items: [Item], total: Int, pages: Int}
  • create(type, new_item, options)Item
  • update(type, id, item_update)Item
  • remove(type, id)Bool

GraphQL methods

  • query(query, context...)

The base query method takes a GraphQL query that may represent a get, find, create, or update, and one or more objects of arguments to pass to the query.

Get

Get a single item with either id or query argument:

query($id: ID) {
    user(id: $id) {id, name, email}
}
query($email: String) {
    user(query: {email: $email}) {id, name, email}
}

Find

Find multiple items, paginated, with a query. Note that the items are wrapped in another object with the shape {items, total, pages}. You can pass an options with {page} for pagination:

query($city: String, $page: Int) {
    users(query: {city: $city}, options: {page: $page}) {items {id, name, email}, total}
}

Create

Mutation query with argument create, which returns the created item:

mutation($name: String, $email: String) {
    create_user(create: {name: $name, email: $email}) {id, name, email}
}

Update

Mutation query with arguments id and update, which returns the updated item:

mutation($id: ID, $name: String) {
    update_user(id: $id, update: {name: $name}) {id, name}
}

Subscriptions

By passing a GraphQL query as second subscription argument you can specify the shape of the event to be returned. The query needs an id argument which will use the created or updated item's id.

task_query = '''
query($id: ID){
    task(id: $id){id, name}
}
'''

client.subscribe 'sconce:data', 'tasks:5:updated', task_query, ({task}) ->
    console.log '[specific task updated, graphql]', task

Without a query, you'll get the object as it is returned from the Db class.

client.subscribe 'sconce:data', 'tasks:created', (task) ->
    console.log '[any task created, raw]', task

Triggers

Attach extra actions before and after creates and updates using triggers, passed as a config argument in the shape {collection: {postCreate: fn, ...}, ...}. Available actions are preCreate, postCreate, and postUpdate.

triggers = {
    tasks: {
        postCreate: (created_task) ->
            console.log 'Look at this task', created_task
    }
}

Authorization

Optionally configure authorization for each type with three dictionaries. By default users will be authorized to perform all actions.

canUpdate = {
    '[type]': (user_id, item_id, cb) ->
        authorized = true # Bool
        cb err, authorized
}
canCreate = {
    '[type]': (user_id, new_item, cb) ->
        cb err, true
}
canRead = {
    '[type]': (user_id, item, cb) ->
        cb err, true
}

You can set the authorization to default to Unauthorized unless a successful access rule is specified with config.strict_auth = true.

The service will then offer an authorized version of each generic method, with a user_id as an additional first argument.

createAs = (user_id, args...) ->
    # optional type-wise canCreate
    @create args...

getAs = (user_id, args...) ->
    # optional type-wise canRead
    @get args...

findAs = (user_id, args...) ->
    # optional type-wise canRead
    @find args...

updateAs = (user_id, args...) ->
    # optional type-wise canUpdate
    @update args...

queryAs = (user_id, query, context) ->
    # substitute getAs, findAs for get, find...
    query query, context

# Create a LocalDB with some triggers and access rules
new DataService 'myproject:data', {
    config: {
        triggers
        canRead:
            tasks: (user_id, item, cb) ->
                get 'users', {id: user_id}, (err, user) ->
                    cb err, user.god == true ||
                        user_id in item.assigned_user_ids
        canUpdate:
            tasks: (user_id, item_id, cb) ->
                get 'users', {id: user_id}, (err, user) ->
                    cb err, user.god
    }
}

Db Subclasses

Implement these methods:

Db = require './db'

class CustomDb extends Db
    _get: (type, query, cb) ->
    _find: (type, query, search, options, cb) ->
    _findWithArray: (type, queries, cb) ->
    _create: (type, new_item, cb) ->
    _update: (type, id, item_update, cb) ->
    _remove: (type, id, cb) ->

FAQs

Package last updated on 20 Mar 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.