API
Generated Modules
src/service-name/service-name.validate.?s
This module exports functions for validating data for that service name.
Exports
{Object} create{Object} update{Object} patch{Function} validateCreate{Function} validateUpdate{Function} validatePatch{Function} quickValidate
| Argument | Type | Description |
|---|---|---|
create | Object | JSON-schema for validation on create. |
update | Object | JSON-schema for validation on update. |
patch | Object | JSON-schema for validation on patch. |
validateCreate | Function | Hook function for validation on create. Signature is validateCreate(ajvOptions). |
validateUpdate | Function | Hook function for validation on update. Signature is validateUpdate(ajvOptions). |
validatePatch | Function | Hook function for validation on patch. Signature is validatePatch(ajvOptions). |
quickValidate | Function | Generic validation function. Signature is quickValidate(method, data, ajvOptions). |
validate... | Parameters | Default | Description |
|---|---|---|---|
| . | {Object} ajvOptions | Options for ajv. |
quickValidate | Parameters | Default | Description |
|---|---|---|---|
| . | {String} method | Type of validation: create, update or patch. | |
| . | {Object} data | The data record. | |
| . | {Object} ajvOptions | Options for ajv. |
- Example
Obtaining the JSON-schema.
Configuring hooks.
Generic validation anywhere.
Details
There are some good tutorials on using JSON-Schema with Ajv.
The hook functions call the common hook validateSchema.
There is no validation module for the service for the GraphQL endpoint.
Service Adapters
graphql
The custom service handling GraphQL requests.
Arguments
{Object} options
| Argument | Type | Default | Description |
|---|---|---|---|
options | Object | Options to configure the service |
options | Property | Used for | Description |
|---|---|---|---|
| . | {Function} schemas | all | Returns GraphQL schemas |
| . | {Function} resolvers | all | Returns GraphQL resolver functions. |
| . | {Function} sqlJoins | SQL | Returns metadata for join-monster. |
| . | {String} dialect | SQL | Dialect of SQL to generate. |
| . | {Function} executeSql | SQL | Execute raw SQL statement. Signaure is executeSql(sqlString). |
| . | {Boolean} logSQL | SQL | Whether to log raw SQL statements to the console. |
| . | {Function} openDb | SQL | Optional function to explicitly open the SQL database. Usually Feathers opens the database automatically. |
| . | {Array(String) | String} extraAuthProps | Non-SQL | Optional additional properties to copy from /graphql params when calling Feathers services. |
- Example
Details
The custom GraphQL schema type JSON is automatically added to (copies of) the schemas and resolvers options. It supports valid JSON values, allowing arguments like
query: { dept: 'a' }.option may contain these optional properties.
- {Array(String) | String} extraAuthProps - See context below.
- {Function} openDB - Function will be called to open SQL database. Feathers will usually automatically open the database.
These properties are added to (a clone of) options and passed to the GraphQL resolver function module.
- convertArgsToFeathers
- convertArgsToParams
- convertArgsToOrderBy - creates SQL ORDER clause from GraphQL arguments.
- convertArgsToWhere - creates SQL WHERE clause from GraphQL arguments.
- extractAllItems
- extractFirstItem
- feathersBatchLoader
- genAndRunSql
- resolverTypes - resolver for JSON scalar type.
- schemaTypes - schema for JSON scalar type.
// .../services/graphql/service.resolvers.js or // .../batchloader.resolvers.js or // .../sql.resolvers.js module.exports = function (app, options) { /* ... */ };context
The content passed to the GraphQL resolver function calls contains
- app - The Feathers app
- provider - params.provider from the /graphql service call.
- user - params.user from the /graphql service call.
- authenticated - params.authenticated from the /graphql service call.
- prop names contained in the extraAuthProps option - Taken from the same prop names in the /graphql service call.
- batchLoaders - An object, initially empty, to cache BatchLoaders created for this GraphQL request.
- cache - An object, initially empty, to cache the contents of select tables.
For example, all the records in users would be cached if another table contains an array of foreign keys to it,
e.g. the members table contains the array
memberIds: [user1, user2, ...]. A cache is used as the Feathers common database API cannot select these records in users, so the cache is scanned to select them.
GraphQL resolver function calls.Errors
GraphQL swallows any other errors if it throws during initialization for a new request. That GraphQL error will be thrown as a Feathers BadRequest error.
The service adapter will reformat other GraphQL errors so they are acceptable to Feathers. Specifically the Feathers message will identify the line number, column number and path in the GraphQL request of the first error detected by GraphQL.
GraphQL errors
GraphQL error messages can be obtuse.
Utility Routines
These routines are used by the generated code handling GraphQL requests. You may be using them should you customize the generated code.
convertArgsToFeathers
Returns a function which will convert the arguments in a GraphQL resolver call into the params for a Feathers service call.
Arguments
{Array(String) | String} extraAuthPropNames
| Argument | Type | Default | Description |
|---|---|---|---|
extraAuthPropNames | {Array(String) | String} | [] | The names of additional authentication properties from the GraphQL call to include in the Feathers service calls. |
Returns
{Function} argsToParamsFunction
| Argument | Type | Description |
|---|---|---|
argsToParamsFunction | Function | A function with signature (args, content, ast, ...moreParams). |
- Example
// src/services/graphql/service.resolvers.?s or /batchloader.resolvers.?s
let moduleExports = function (app, { convertArgsToFeathers }) {
const convertArgs = convertArgsToFeathers('isVerified');
return {
Role: {
users: (parent, args, content, ast) => {
const feathersParams = convertArgs(args, content, ast, {
query: { roleId: parent._id, $sort: undefined }, paginate: false
});
return users.find(feathersParams).then(extractAllItems);
},
}
};
}
Details
convertArgsToFeathers constructs the
paramsfor a Feathers service call containing- provider -
context.providerfrom the GraphQL's service call, - user -
context.user, - authenticated -
context.authenticated, - graphql - The resolver path for the call,
- query -
args.query. - property values provided by
moreParams, - property names specified by
extraAuthPropNames.
- provider -
convertArgsToParams
Replace all property names starting with __ with ones starting with $.
Arguments
{Object} obj
| Argument | Type | Default | Description |
|---|---|---|---|
obj | {Object} | The object containing the properties. |
Returns
{Object} $obj
| Argument | Type | Description |
|---|---|---|
$obj | Object | The object with renamed properties. |
- Example
// src/services/graphql/service.resolvers.?s or /batchloader.resolvers.?s
let moduleExports = function (app, { convertArgsToParams }) {
console.log(
convertArgsToParams({ a: 1, __b: { __c: 3, d: 4 } }) // { a: 1, $b: { $c: 3, d: 4 } }
);
}
Details
This function is not directly called within the generated code. It is called by convertArgsToFeathers.
A null or undefined object is returned as is.
extractAllItems
Returns an array of the records returned by the service call.
Arguments
{Object} serviceCallResult
| Argument | Type | Default | Description |
|---|---|---|---|
serviceCallResult | Object | The result of a Feathers service call. |
Returns
{Array(Object) | null} records
| Argument | Type | Description |
|---|---|---|
records | Array(Object) | null | The records contained in the service call. |
- Example
// src/services/graphql/service.resolvers.?s or /batchloader.resolvers.?s
let moduleExports = function (app, { extractAllItems }) {
const userRecords = app.service('users').find()
.then(result => extractAllItems(result));
}
Details
Returns an array of the records returned by the service call. The array may have 0 elements.
nullis returned ifserviceCallResultorserviceCallResult.datais falsey.
extractFirstItem
Returns the single record returned by the service call.
Arguments
{Object} serviceCallResult
| Argument | Type | Default | Description |
|---|---|---|---|
serviceCallResult | Object | The result of a Feathers service call. |
Returns
{Object | null} record
| Argument | Type | Description |
|---|---|---|
record | Object | null | The single record contained in the service call. |
- Example
// src/services/graphql/service.resolvers.?s or /batchloader.resolvers.?s
let moduleExports = function (app, { extractFirstItem }) {
const userRecords = app.service('users').get(0)
.then(result => extractFirstItem(result));
}
Details
Returns an array of the records returned by the service call. The array may have 0 elements.
nullis returned ifserviceCallResultorserviceCallResult.datais falsey, or if there is no record.Throws if there are multiple records.
feathersBatchLoader
Creates a batch-loader.
Arguments
{String} resolverName}{String} graphqlType{String|Function} serializeRecordKey1{Promise} getRecords{Number} maxBatchSize{Number} maxCacheSize{String|Function} serializeBatchLoaderKey1
| Argument | Type | Default | Description |
|---|---|---|---|
resolverName | String | Name of resolver. Only used in info/error logs. | |
graphqlType | String | Type of GraphQL result to return for each BatchLoader key | |
serializeRecordKey1 | {String|Function} | Serialize record key. Return serialized key from record, identical to that produced by serializeBatchLoaderKey1. Function - record => serialized key. String - Converts to record => record[serializeRecordKey1].toString(); | |
getRecords | Promise | Feathers call to read records given [keys] from BatchLoader. Can return a '.get()' object or array, else a paginated or non-paginated '.find()' object. An error is caught and processed as an empty array. | |
maxBatchSize | Number | Maximum number of keys getRecords is called with. | |
maxCacheSize | Number | Maximum number of items in the cache. Will use LRU cache. | |
serializeBatchLoaderKey1 | {String | Function} | Serialize key from BatchLoader.load(), identical to that produced by serializeRecordKey1. Function - key => serialized key e.g. '1' or '{"name":"a","age":20}'. String - Converts to key => key.toString(); |
graphqlType | Value | Description |
|---|---|---|
| . | [!]! | required collection of required elements |
| . | [!] | optional collection of required elements |
| . | [] | optional collection of optional elements |
| . | ! | required object |
| . | `` | optional object |
Returns
{Function} batchLoader
| Argument | Type | Description |
|---|---|---|
batchLoader | Function | A batch-loader. |
- Example
// src/services/graphql/batchloader.resolvers.?s
let moduleExports = function batchLoaderResolvers(app, options) {
let { convertArgsToFeathers, feathersBatchLoader: { feathersBatchLoader } } = options;
const convertArgs = convertArgsToFeathers([]);
const defaultPaginate = app.get('paginate');
const maxBatchSize = defaultPaginate && typeof defaultPaginate.max === 'number' ?
defaultPaginate.max : undefined;
const roleUsersBatchLoader = feathersBatchLoader('Role.users', '[!]', 'roleId',
keys => {
const feathersParams = convertArgs(args, content, null, {
query: { roleId: { $in: keys }, $sort: undefined },
_populate: 'skip', paginate: false
});
return users.find(feathersParams);
},
maxBatchSize // Max #keys in a BatchLoader func call.
);
}
genAndRunSql
Runs a raw SQL statement.
Arguments
{Function} execSql{Object} jmOptions{Object} options
| Argument | Type | Default | Description |
|---|---|---|---|
execSql | Function | Function to execute a raw SQL statement. | |
jmOptions | {Object} | {} | Options for join-monster. |
options | {Object} | {} | { logSQL } will log the raw SQL statements to the console. |
Returns
- `{Function} callJoinMonster
| Argument | Type | Description |
|---|---|---|
callJoinMonster | Function | A function with signature (context, info). |
- Example
// src/services/graphql/sql.resolvers.?s
let moduleExports = function sqlResolvers(app, options) {
let { dialect, executeSql, genAndRunSql } = options;
let genRunSql = genAndRunSql(executeSql, { dialect }, options);
return {
Query: {
getUser: (parent, args, content, ast) => genRunSql(content, ast),
findUser: (parent, args, content, ast) => genRunSql(content, ast)
}
};
}