• Stars
    star
    112
  • Rank 311,076 (Top 7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 9 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Service adapters for KnexJS a query builder for PostgreSQL, MySQL, MariaDB, Oracle and SQLite3

Important: This module has been moved to @feathersjs/knex and is developed in feathersjs/feathers

feathers-knex

CI Download Status

A database adapter for KnexJS, an SQL query builder for Postgres, MSSQL, MySQL, MariaDB, SQLite3, and Oracle.

npm install --save mysql knex feathers-knex

Important: feathers-knex implements the Feathers Common database adapter API and querying syntax.

Note: You also need to install the database driver for the DB you want to use.

API

service(options)

Returns a new service instance initialized with the given options.

const knex = require('knex');
const service = require('feathers-knex');

const db = knex({
  client: 'sqlite3',
  connection: {
    filename: './db.sqlite'
  }
});

// Create the schema
db.schema.createTable('messages', table => {
  table.increments('id');
  table.string('text');
});

app.use('/messages', service({
  Model: db,
  name: 'messages'
}));
app.use('/messages', service({ Model, name, id, events, paginate }));

Options:

  • Model (required) - The KnexJS database instance
  • name (required) - The name of the table
  • schema (optional) - The name of the schema table prefix (example: schema.table)
  • id (optional, default: 'id') - The name of the id field property.
  • events (optional) - A list of custom service events sent by this service
  • paginate (optional) - A pagination object containing a default and max page size
  • multi (optional) - Allow create with arrays and update and remove with id null to change multiple items. Can be true for all methods or an array of allowed methods (e.g. [ 'remove', 'create' ])
  • whitelist (optional) - A list of additional query parameters to allow (e..g [ '$regex', '$geoNear' ]). Default is the supported operators

adapter.createQuery(query)

Returns a KnexJS query with the common filter criteria (without pagination) applied.

params.knex

When making a service method call, params can contain an knex property which allows to modify the options used to run the KnexJS query. See customizing the query for an example.

Example

Here's a complete example of a Feathers server with a messages SQLite service. We are using the Knex schema builder and SQLite as the database.

$ npm install @feathersjs/feathers @feathersjs/errors @feathersjs/express @feathersjs/socketio feathers-knex knex sqlite3

In app.js:

const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');

const service = require('feathers-knex');
const knex = require('knex');

const db = knex({
  client: 'sqlite3',
  connection: {
    filename: './db.sqlite'
  }
});

// Create a feathers instance.
const app = express(feathers());
// Turn on JSON parser for REST services
app.use(express.json());
// Turn on URL-encoded parser for REST services
app.use(express.urlencoded({ extended: true }));
// Enable REST services
app.configure(express.rest());
// Enable Socket.io services
app.configure(socketio());
// Create Knex Feathers service with a default page size of 2 items
// and a maximum size of 4
app.use('/messages', service({
  Model: db,
  name: 'messages',
  paginate: {
    default: 2,
    max: 4
  }
}))
app.use(express.errorHandler());

// Clean up our data. This is optional and is here
// because of our integration tests
db.schema.dropTableIfExists('messages').then(() => {
  console.log('Dropped messages table');

  // Initialize your table
  return db.schema.createTable('messages', table => {
    console.log('Creating messages table');
    table.increments('id');
    table.string('text');
  });
}).then(() => {
  // Create a dummy Message
  app.service('messages').create({
    text: 'Message created on server'
  }).then(message => console.log('Created message', message));
});

// Start the server.
const port = 3030;

app.listen(port, () => {
  console.log(`Feathers server listening on port ${port}`);
});

Run the example with node app and go to localhost:3030/messages.

Querying

In addition to the common querying mechanism, this adapter also supports:

$and

Find all records that match all of the given criteria. The following query retrieves all messages that have foo and bar attributes as true.

app.service('messages').find({
  query: {
    $and: [
      {foo: true},
      {bar: true}
    ]
  }
});

Through the REST API:

/messages?$and[][foo]=true&$and[][bar]=true

$like

Find all records where the value matches the given string pattern. The following query retrieves all messages that start with Hello:

app.service('messages').find({
  query: {
    text: {
      $like: 'Hello%'
    }
  }
});

Through the REST API:

/messages?text[$like]=Hello%

$notlike

The opposite of $like; resulting in an SQL condition similar to this: WHERE some_field NOT LIKE 'X'

app.service('messages').find({
  query: {
    text: {
      $notlike: '%bar'
    }
  }
});

Through the REST API:

/messages?text[$notlike]=%bar

$ilike

For PostgreSQL only, the keywork $ilike can be used instead of $like to make the match case insensitive. The following query retrieves all messages that start with hello (case insensitive):

app.service('messages').find({
  query: {
    text: {
      $ilike: 'hello%'
    }
  }
});

Through the REST API:

/messages?text[$ilike]=hello%

Transaction Support

The Knex adapter comes with three hooks that allows to run service method calls in a transaction. They can be used as application wide (app.hooks.js) hooks or per service like this:

// A common hooks file
const { hooks } = require('feathers-knex');

const { transaction } = hooks;

module.exports = {
  before: {
    all: [ transaction.start() ],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  },

  after: {
    all: [ transaction.end() ],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  },

  error: {
    all: [ transaction.rollback() ],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  }
};

To use the transactions feature, you must ensure that the three hooks (start, end and rollback) are being used.

At the start of any request, a new transaction will be started. All the changes made during the request to the services that are using the feathers-knex will use the transaction. At the end of the request, if sucessful, the changes will be commited. If an error occurs, the changes will be forfeit, all the creates, patches, updates and deletes are not going to be commited.

The object that contains transaction is stored in the params.transaction of each request.

Important: If you call another Knex service within a hook and want to share the transaction you will have to pass context.params.transaction in the parameters of the service call.

Customizing the query

In a find call, params.knex can be passed a KnexJS query (without pagination) to customize the find results.

Combined with .createQuery({ query: {...} }), which returns a new KnexJS query with the common filter criteria applied, this can be used to create more complex queries. The best way to customize the query is in a before hook for find.

app.service('messages').hooks({
  before: {
    find(context) {
      const query = context.service.createQuery(context.params);

      // do something with query here
      query.orderBy('name', 'desc');

      context.params.knex = query;
      return context;
    }
  }
});

Configuring migrations

For using knex's migration CLI, we need to make the configuration available by the CLI. We can do that by providing a knexfile.js (OR knexfile.ts when using TypeScript) in the root folder with the following contents:

knexfile.js

const app = require('./src/app')
module.exports = app.get('postgres')

OR

knexfile.ts

import app from './src/app';
module.exports = app.get('postgres');

You will need to replace the postgres part with the adapter you are using. You will also need to add a migrations key to your feathersjs config under your database adapter. Optionally, add a seeds key if you will be using seeds.

// src/config/default.json
...
  "postgres": {
    "client": "pg",
    "connection": "postgres://user:password@localhost:5432/database",
    "migrations": {
      "tableName": "knex_migrations"
    },
    "seeds": {
      "directory": "../src/seeds"
    }
  }

Then, by running: knex migrate:make create-users, a migrations directory will be created, with the new migration.

Error handling

As of version 4.0.0 feathers-knex only throws Feathers Errors with the message. On the server, the original error can be retrieved through a secure symbol via error[require('feathers-knex').ERROR]

const { ERROR } = require('feathers-knex');

try {
  await knexService.doSomething();
} catch(error) {
  // error is a FeathersError with just the message
  // Safely retrieve the Knex error
  const knexError = error[ERROR];
}

Waiting for transactions to complete

Sometimes it can be important to know when the transaction has been completed (committed or rolled back). For example, we might want to wait for transaction to complete before we send out any realtime events. This can be done by awaiting on the transaction.committed promise which will always resolve to either true in case the transaction has been committed, or false in case the transaction has been rejected.

app.service('messages').publish((data, context) => {
  const { transaction } = context.params

  if (transaction) {
    const success = await transaction.committed
    if (!success) {
      return []
    }
  }

  return app.channel(`rooms/${data.roomId}`)
})

This also works with nested service calls and nested transactions. For example, if a service calls transaction.start() and passes the transaction param to a nested service call, which also calls transaction.start() in it's own hooks, they will share the top most committed promise that will resolve once all of the transactions have succesfully committed.

License

Copyright (c) 2021

Licensed under the MIT license.

More Repositories

1

feathers-vuex

Integration of FeathersJS, Vue, and Nuxt for the artisan developer
TypeScript
445
star
2

authentication

[MOVED] Feathers local, token, and OAuth authentication over REST and Websockets using JSON Web Tokens (JWT) with PassportJS.
JavaScript
317
star
3

feathers-authentication-management

Adds sign up verification, forgotten password reset, and other capabilities to local feathers-authentication
TypeScript
246
star
4

feathers-swagger

Add documentation to your FeatherJS services and feed them to Swagger UI.
JavaScript
225
star
5

feathers-sync

Synchronize service events between Feathers application instances
JavaScript
222
star
6

feathers-reactive

Reactive API extensions for Feathers services
TypeScript
216
star
7

feathers-sequelize

A Feathers service adapter for the Sequelize ORM. Supporting MySQL, MariaDB, Postgres, SQLite, and SQL Server
TypeScript
208
star
8

feathers-react-native-chat

A React Native example chat app using feathers
JavaScript
196
star
9

feathers-hooks-common

Useful hooks for use with FeathersJS services.
TypeScript
193
star
10

feathers-mongoose

Easily create a Mongoose Service for Feathersjs.
JavaScript
189
star
11

feathers-permissions

Simple role and service method permissions for Feathers
JavaScript
184
star
12

cli

The command line interface for scaffolding Feathers applications
JavaScript
155
star
13

feathers-mongodb

A mongodb service for feathers
JavaScript
122
star
14

generator-feathers

A Yeoman generator for a Feathers application
JavaScript
120
star
15

feathers-authentication-hooks

Useful hooks for authentication and authorization
JavaScript
115
star
16

feathers-redux

Integrate Feathers with your Redux store
JavaScript
114
star
17

client

[MOVED] Client side Feathers build
JavaScript
111
star
18

feathers-chat-vuex-0.7

Feathers Chat application build using feathers-vuex
CSS
102
star
19

feathers-objection

Feathers database adapter for Objection.js, an ORM based on KnexJS SQL query builder for Postgres, Redshift, MSSQL, MySQL, MariaDB, SQLite3, and Oracle. Forked from feathers-knex.
JavaScript
98
star
20

feathers-chat-react

Feathers Chat application build using React and create-react-app
JavaScript
97
star
21

feathers-batch

Batch multiple Feathers service calls into one
JavaScript
96
star
22

feathers-stripe

TypeScript
95
star
23

feathers-blob

Feathers service for blob storage, like S3.
JavaScript
92
star
24

feathers-rethinkdb

A Feathers service adapter for RethinkDB.
JavaScript
85
star
25

feathers-nedb

A service using NeDB, an embedded datastore for Node.js
TypeScript
83
star
26

feathers-mailer

Feathers mailer service using nodemailer
TypeScript
83
star
27

feathers-elasticsearch

Feathersjs adapter for Elasticsearch
JavaScript
78
star
28

validate-joi

Feathers hook utility for schema validation, sanitization and client notification using Joi.
JavaScript
67
star
29

feathers-hooks

Service method hooks for easy authorization and processing
JavaScript
59
star
30

feathers-chat-ts

A Feathers real-time chat application in TypeScript
TypeScript
54
star
31

feathers-rest

The Feathers HTTP(S) transport plugin for REST APIs
JavaScript
52
star
32

feathers-chat-angular

An angular implementation of a feathers-chat client
TypeScript
52
star
33

feathers-chat-vuex

Feathers Chat built with Feathers-Vuex 3.0
CSS
50
star
34

feathers-swift

FeathersJS Swift SDK, written with love.
Swift
50
star
35

feathers-memory

An in memory feathers service
JavaScript
44
star
36

authentication-client

[MOVED] The authentication client
JavaScript
41
star
37

feathers-localstorage

A client side service based on feathers-memory that persists to LocalStorage
JavaScript
38
star
38

socketio

[MOVED] The Feathers Socket.io websocket transport plugin
JavaScript
37
star
39

schema

JavaScript and TypeScript schema definitions
TypeScript
35
star
40

errors

[MOVED] Feathers errors for server and client
JavaScript
35
star
41

authentication-jwt

[MOVED] JWT authentication strategy for feathers-authentication using Passport
JavaScript
30
star
42

configuration

[MOVED] A plugin for configuring a Feathers application
JavaScript
28
star
43

feathers-profiler

Log feathers service calls and gather profile information on them.
JavaScript
27
star
44

feathers-bootstrap

Feathers application bootstrap and configuration using JSON files
JavaScript
26
star
45

authentication-oauth2

[MOVED] OAuth 2 plugin for feathers-authentication
JavaScript
26
star
46

feathers-mailgun

A Feathers service for Mailgun
JavaScript
26
star
47

authentication-local

[MOVED] Local authentication plugin for feathers-authentication
JavaScript
26
star
48

feathers-logger

A little wrapper for convenient logging in feathers
JavaScript
23
star
49

feathers-debugger

Feathers Debugger Chrome extension
JavaScript
23
star
50

generator-feathers-plugin

A Yeoman generator for creating a FeathersJS plugin.
JavaScript
22
star
51

feathers-waterline

A Feathers adapter for the Waterline ORM
JavaScript
21
star
52

feathers-service-tests

A test harness for Feathers service implementations
JavaScript
20
star
53

feathers-authentication-ldap

LDAP authentication strategy for feathers-authentication using Passport
JavaScript
19
star
54

primus

[MOVED] The Feathers Primus websocket transport plugin
JavaScript
18
star
55

feathers-levelup

LevelUP instances as Feathers services
JavaScript
14
star
56

feathers-authentication-popups

Server and client utils for implementing popup-based authentication flows
JavaScript
14
star
57

batch-loader

Reduce requests to backend services by batching calls and caching records.
JavaScript
13
star
58

express

[MOVED] Feathers Express framework bindings and REST transport plugin
JavaScript
13
star
59

feathers-query-filters

Adds support for special query string params used for filtering data
JavaScript
12
star
60

commons

[MOVED] Shared utility functions
JavaScript
11
star
61

transport-commons

[MOVED] Shared functionality for Feathers transports
JavaScript
11
star
62

feathers-mongodb-management

Manage MongoDB Databases, Users & Collections with this Feathers service adapter
JavaScript
11
star
63

feathers-generator

A metalsmith based generator for scaffolding Feathers apps.
JavaScript
10
star
64

feathers-debugger-service

Feathers Debugger service, use with Feathers Debugger.
JavaScript
9
star
65

feathers-cassandra

Feathers service adapter for Cassandra DB based on Express-Cassandra ORM and CassanKnex query builder
JavaScript
8
star
66

rest-client

[MOVED] REST client services for different Ajax libraries
JavaScript
8
star
67

feathers-android

Android client for feathers services
Java
7
star
68

feathers-swift-socketio

FeathersSwift SocketIO Transport Provider
Swift
7
star
69

feathers-twilio

A Feathers service for talking to the Twilio API
JavaScript
7
star
70

website

The old Feathers website
Less
6
star
71

dataloader

JavaScript
6
star
72

feathers-authentication-custom

Custom authentication strategy for feathers-authentication using Passport
JavaScript
5
star
73

authentication-oauth1

[MOVED] A Feathers OAuth1.x authentication strategy
JavaScript
5
star
74

socketio-client

[MOVED] Client services for Socket.io and feathers-socketio
JavaScript
5
star
75

primus-client

[MOVED] Client services for Primus and feathers-primus
JavaScript
5
star
76

feathers-redis

A Feathers redis service adapter
JavaScript
4
star
77

tools

Codemods and other generator and repository management tools
JavaScript
3
star
78

feathers-couchbase

A Couchbase Service for feathers
JavaScript
3
star
79

feathers-swift-rest

REST Transport provider for FeathersSwift
Swift
2
star
80

feathers-ios

Feathers service client for iOS
Swift
2
star
81

feathers-sendgrid

Sendgrid service for Feathers
JavaScript
1
star