Download as:
Rating : ⭐⭐⭐⭐⭐
Price: $10.99
Language:EN
Pages: 54

Hidden bydefault list the users const res broker

const check = v.compile(schema);

check({ name: "John", age: 42 }); // Valid
check({ name: "John" }); // Valid
check({ age: 42 }); // Fail because name is required
Nullable
If you want disallow undefined value but allow null value, use nullable instead of optional .

null is a valid input for nullable fields that has default value.

const schema = {
about: { type: "string", nullable: true, default: "Hi! I'm using javascript" } }
const check = v.compile(schema)

const schema = {
name: { type: "string" }, // required
$$strict: true // no additional properties allowed }

const check = v.compile(schema);

It is possible to define more validators for a field. In this case, only one validator needs to succeed for the field to be valid.

const schema = {
cache: [
{ type: "string" },
{ type: "boolean" }
]
}

fields
scopes
defaultScopes
defaultPopulates
indexes

options available on only method nor on action nor on schema

limit
offset
fields
sort
search
searchFields
collation
scope
populate
query

option available on Fields schema only, there are tonnes beside important listed below

• virtual : true

• hidden : true

• set

• populate

opts.scope is only available on three methods and those are

• updateEntity

Hence below params will not work in action list, thinking we can set the value params for the action list. Becauae as stated earlier params key inside the action here list object can only act as validation schema.

So, from section options only meta and other variable will be set that is given in signature of action pdf.

How to parse query string, Query string parameters. More information: https://github.com/ljharb/qs

like fields:{
username: { type: string ,

Logger

required: true}

readonly: true => readonly property can be set by the local service only. Any incoming data from api service or any other service can't set it. Only local service can set it by defining a method in the field property itself. In order to set the value we have to define default, set method or other operation hooks for setting the value of read-only fields.

Immutable: true => Immutable fields value can be set only once and once set, it cant be changed in the future. However during the query we can use permissive = true that will ignore the immutable data and still let you change the value.

will be present if it is marked hidden by default, if it is marked as true than it will not be prsent.

})

Scope

Similarly scopes checking doesn't come magically, we have to define method to check scope, If we don't implement scopeAuthrity then anyone one can remove scope.

Fields

The field definition is similar to Fastest Validator schemas. You can define them in the same format and the service uses the Fastest Validator to validate and sanitize the input data. The difference between this schema and FV schema is that here all defined fields are optional (just like the fields in the Database Engines). You should set the property required: true for mandatory fields. i.e for validator , require is true by default, for db, require is false by default

Example

Field properties
type : <string> (no default value, it's a required property)
The type defines the type of the field value. It can be any primitive type ( boolean , number , string , object , array ) or any type from Fastest Validator types. If the type is not a valid database type, you should define the columnType property with a valid database field type as well.

{ id: "abc123",
username: "John Doe",

Example { title: { type: "string", required: true } }

What above means, if you set any field required and if it is not in the context params then it will through error for creating and replace action. Though it has default value or any value doesn't matter.

Validation error

secure
secure:<boolean<(default:false) With the secure property you can encrypt the value of the ID field. This can be useful to prevent users from finding out the IDs of other documents when the database uses incremental ID values. To use it, you should define encodeID(id) and decodeID(id) methods in the service that performs the encoding/decoding operations. The hashids lib can generate Youtube-like alphanumeric IDs from number(s) or from Mongo's ObjectID .

Example secure ID using hashids lib`

}}, // ... more fields

methods: {
encodeID(id) {
return id != null ? hashids.encodeHex(id) : id; }, decodeID(id) {
return id != null ? hashids.decodeHex(id) : id; }}}
Please note that the methods should be synchronous.

Example

lastLogin: { type: "date", columnType: "datetime" }, createdAt: { type: "number", columnType: "bigInteger" } } The value of columnType depends on the used adapter and database engine.

default: <string|Function> (Default: null) => For the non-required fields, you can set default values. If the field value is null or undefined in the create and replace actions, the service will set the defined default value. If the default is a Function, the service will call it to get the default value. The function may be asynchronous.

Property Type Callback parameters
Context

any

Value of the field.

Object
Object

id

any

String
Object

At updating, replacing and removing, it contains the original raw (not transformed) entity.

root

Object
Example

Immutable: <boolean> (Default: false ) = > The immutable field means that you can set the value once. It cannot be changed in the future. Example {accountType: { type: "string", immutable: true }}
virtual : <boolean> (Default: false ) = >The virtual field returns a value that does not exist in the database. It's mandatory to define the get method that returns the value of the field.

{ fullName: {
type: "string",
virtual: true,
get: ({ entity }) => `${entity.firstName} ${entity.lastName}` }}
hidden : <boolean|String> (Default: false ) = > The hidden fields are skipped from the response during transformation.

List the users with createdAt const res = broker.call("users.find", {fields: ["name", "createdAt", "password"]}) The response contains the name and createdAt fields

validate <Function|String> (Default: null ) = >With validate , you can configure your custom validation function. If it is a string, it should be a service method name that will be called. It can be asynchronous. The function should return true if the input value is valid or with a String if not valid. The returned text will be used in the ValidationError as the message of error. Example with validation error.

get is used when we want to transform the result to some other value during fetching, so whatever is stored in db and we want to change before sending it back to caller, we can use get method. However if we dint use get method that doesn't mean we will not get value what is stored in db. By default it returns the value stored in db without using get function in schema.

Callback parameters

Type Description
Context
any
Object

The whole received object ( ctx.params ).

Object

Field schema.

Object

} }

set: <Function> (Default: null) => The set function is called when creating or updating entities. You can change the input value or calculate a new one from other values of the entity. If it is a String , it should be a service method name that will be called. It can be asynchronous.

set: ({ params }) => `${params.firstName} ${params.lastName}` },
email: { type: "string", set: value => value.toLowerCase() }}

It can be asynchronous.

Callback parameters

Property

Type

Description
ctx Context

Moleculer Context instance. It can be null .

value
params
field

Object

Field schema.

id any
operation String
entity Object
root Object

Callback parameters

Property {

Type

Description
ctx
value
params

Object

The whole received object ( ctx.params ).

field
id
operation

String

Type of operation. Available values: create , update , replace , remove .

entity
root

Example

updatedAt: {

updatedBy: {

type: "string",

Callback parameters

Example

If you want to cherry pick the actions that are auto created, also if you want to set visibility of actions you can set actionVisibility in mixing.

The service generates common CRUD actions if the createActions mixin option is not false . You can finely control which actions should be created.

module.exports = {
mixins: [DbService({

Type

Default

Description

Max count of rows.

Fields for search. see blow for more about search fields are not used in mongoDB
Collation settings. Passed for adapter directly. Scopes for the query. If false, the default scopes are disabled.

Populated fields.

While other database might supports search like solr which allow us to search on a specific fields or more than specific fields where are mongo creates one text index for one collection and it automatically look for the text type of data fields and create text index by merging all the text type fields.

For more on full text search watch below

status: true,
votes: {
$gt: 5
}
}

} );

[
{
id: "akTRSKTKzGCg9EMz",
title: "Third post",
content: "Content of my 3rd post...", Results votes: 0, status: false,
createdAt: 1618077045354,
},
{
id: "0YZQR0oqyjKILaRn",
title: "My second post",
content: "Content of my second post...", votes: 3,
status: true,
createdAt: 1618077045352,
}
]

Examples Limit & offset const posts = await broker.call("posts.find", { limit: 10, offset: 50 });

const posts = await broker.call("posts.find", {

Searching

2. listList entities with pagination. It returns also the total number of rows. Parameters

Property

Default

Fields to return.

Sorted fields.

Populated fields.

Query object. If String , it's converted with JSON.parse

null
null

fields

String|Array<String>

null
null
null
searchFields

String|Array<String>

null

collation

null
null

String|Array<String>

null

query

null
{ rows: [
{

title: "Third post",

content: "Content of my 3rd post...",

Results },

Examples Pagination The other parameter examples are the same as for the find action.

const posts = await broker.call("posts.list", { page: 3, pageSize: 10 });

Examples

4. getGet an entity by ID, select which fields should be return, pass id.

status: true,
createdAt: 1618077608593 }
Code example
const post = await broker.call("posts.get", { id: "YVdnh5oQCyEIRja0" });

Different ID field:
If you want to use another primary key field name instead of id , you should also use it in the action parameters.

Type
Description

<id>

any|Array<any>

null
null

scope

String|Array<String>|Boolean

null
null

Populated fields.

mapping

false
throwIfNotExist
false

If true , the error EntityNotFound is thrown

if the entity does not exist.

reorderResult
false

No endpoint.

Examples Call with a single ID

const post = await broker.call("posts.resolve", { id: ["YVdnh5oQCyEIRja0", "Di5T8svHC9nT6MTj"] });

});

{

The other parameter examples are the same as for the find action.

6. create Create an entity Create an entity.

Examples

title: "My first post",
content: "Content of my first post..."

Parameters There are no special parameters. All fields are used after validation for the entities.

REST endpointNot configured.

},
{
title: "My second post",
content: "Content of my second post..."
}
]);

[
{
id: "YVdnh5oQCyEIRja0",
title: "My first post",

Parameters

Property Type Default Description

<id>

any null

Examples

id: "YVdnh5oQCyEIRja0",
title: "Modified title",

9. replace Replace an entity

Replace an existing entity. The difference between replace and update that replace replaces the whole entity. This means that you should specify all required entity fields. This function doesn't merge the new and old entity.

Parameters Property Type Default Description
any null

ResultsReturn the replaced entity.

Examples
Result {

content: "Content of my first post...",

votes: 10,

updatedAt: 1618082167005

votes: 10,

action name : remove

11. Custom actions To add your own actions, simply create them under actions and call the built-in methods.

sanitizeParams(params: object, opts?: object): Sanitize the input parameters for find , list and count actions.

Options

Type Default Description
Boolean false
Boolean
false If true , the page and pageSize parameters (for list action) are sanitized.

You can not use throwIfNotExist for any method except resolveEntities and one more
findEntity(ctx?: Context, params: object, opts?: object):Find an entity by query & sort. It returns only the first row of the result.

findEntities(ctx?: Context, params: object, opts?: object): Find entities by query. Parameters

Type Default Description
Context null
Object null

Parameters for search. It's same as find action parameters

Object {}

Other options for internal methods.

opts.transform Boolean true
Property Type
Description
Context null

params

Object

null Parameters for search. It's same ascount action parameters, below I have listed the parameter from count function

resolveEntities(ctx?: Context, params: object, opts?: object) => Return entity(ies) by ID(s).

Type
Description
Context null

Moleculer Context instance. It can be null .

null

Parameters for search. It's same as resolve action parameters

{}

Other options for internal methods.

opts.transform

Boolean true
false
opts.reorderResult boolean false

Note that there is no singular form of resolveEntities method

const user = await this.resolveEntities(ctx, ctx.params, { transform: false }); let userd = await this.resolveEntities(ctx, { id: token.owner });
const usere = await this.resolveEntities(ctx, { id: token.owner });
let userf = await this.resolveEntities(ctx, { id: token.owner });
const userg = await this.resolveEntities(ctx, { id: ctx.meta.userID }); const userh = await this.resolveEntities(ctx, decoded, { transform: false });

);

const _userb = await this.resolveEntities(
ctx,
{ id: ctx.meta.userID },
{ transform: false }
);

Default Description

Context

null

Array<Object>

opts

Boolean

true

false

update and field permission is not checked.

opts.returnEntities

Boolean

false If true , it returns the inserted entities instead of IDs.

Property

Type Default Description

ctx

Context null
Object null
Object null

The query for finding entities.

params.scope

String Array
Object null
Object {}

opts

opts.raw

Boolean false
Boolean true
Boolean false
If true , readonly and immutable fields can be set and update and field permission is not checked.

removeEntity(ctx?: Context, params: object, opts?: object)Delete an entity by ID. The method returns only the ID of the deleted entity.

Type
Description
Context null

params

Object

null
{}

opts.transform

Boolean true

If false , the result won't be transformed.

Array
Boolean null

Disable the enabled soft-delete feature. Only false value is

acceptable.

Property Type Default Description
Context null

Moleculer Context instance. It can be null .

params

Object

null

transformResult(adapter: Adapter, docs: object|Array<object>, params?: object, ctx?: Context) It transforms the entities coming from the database according to the definitions of the fields .

Default Description

Adapter

required

Adapter instance.

Object|Array<Object>
required
null

Entitiy field values.

ctx

null
Moleculer Context instance. It can be null .

getAdapterByContext(ctx?: Context, adapterDef?: object) For multi-tenancy, you should define this method which creates an Adapter definition by the Context .

It should return an Array with two values. The first is a cache key, the second is the adapter definition. The service uses the cache key to store the created adapter. Therefore in the next time, if the cache key is present in the cache, the service won't create a new adapter instance but will use the previous one.

encodeID(id: any) => You should define it when you use secure primary key to encrypt the IDs before returning them.

decodeID(id: any) => You should define it when you use secure primary key to decrypt the received IDs.

ctx

Context

Moleculer Context instance. It can be null .

permission
params
field

Object

Field definition.

Property Type Description
ctx Context
Parameters name String
operation String
scope any

Scope definition.

Scopes

Scopes

The scopes allow you to add constraints for all query methods, like find , list or count . You can use them with soft-delete feature if you want to list only non-deleted entities. You can define your scopes in the service settings and set the default scopes.

name: "posts",

mixins: [DbService(/*...*/)],

status: true

},

},

// It's a custom Function to modify the query object directly. It can be async, as well.

return q;

}},

List the active posts without scope definition

const activePosts = await broker.call("posts.find");

List all public posts

const activePublicPosts = await broker.call("posts.find", { scope: "public" });

List the active & public posts
List all posts disabling the default scope(s) const activePosts = await broker.call("posts.find", { scope: false });

You can define the indexes in the service settings.indexes property. It has a common format and each adapter will process and create the indexes. Another way, if you call the this.createIndex method directly. see below image Index definition Properties

Streaming The service has a streamEntities method that returns the entities by the query similar to the findEntities . But this method returns a Stream instance instead of all rows.

Action for streaming

There is no predefined action for the method, by default. But you can easily create one:

Nested objects & arrays

The document-based database engines generally handle nested objects & arrays. You can also use them in the field definitions. The definition is similar to Fastest Validator nested object schema.

Example for nested object field

module.exports = {
// ...

settings: {

module.exports = {
// ...

settings: {
fields: {
phones: {
type: "array",
items: {
type: "object",
properties: {
type: { type: "string" },
number: { type: "string", required:true} primary: { type: "boolean", default: false }

}}}}};

Populating: The service allows you to easily populate fields from other services. For example: If you have an author field in the posts entity, you can populate it with users service by the author's ID. If the field is n Array of IDs, it will populate all entities with only one request.

verified: { type: "boolean", permission: "admin" }
}},
methods: {
// If we defined the necessary permissions in the fields, we should write // the permission checking logic into the `checkFieldAuthority` method.

async checkFieldAuthority(ctx, permission, params, field) {
const roles = ctx.meta.user.roles || [];
// Returns `true` if the logged in user's role field contains the required role.

scopes: {
notDeleted: {
deletedAt: { $exists: false }
},
},

List all posts (also deleted entities)

module.exports = {
name: "posts",
mixins: [DbService(/*...*/)],
settings: {/* ... */},
methods: {
/**
* Check the scope authority. Should be implemented in the service.

Example

const row = await this.updateEntity(ctx, { id: docs.johnDoe.id,
$set: {
status: false,
height: 192
},
$inc: {
age: 1
},
$unset: {
dob: true
}
}, { raw: true });

$set : it update the field value, if field is not present then it sets the value i.e. insert a new field with value. $push adds or create single elements to a array fields

Caching: The service has a built-in caching mechanism. If a cacher is configured in the ServiceBroker, the service caches the responses of find , list , get and resolve actions and clears the cache if any entities have been modified. Caching is enabled by default and uses the event name cache.clean.{serviceName} (e.g. cache.clean.posts ) to delete cached entries. To disable it, set cache.enabled = false in Mixin options.

Under the hood To cache the responses, the service uses the built-in action caching mechanism of ServiceBroker. The cache clearing is a bit complicated because if you are running multiple instances of the service with a local Memory cache, you should notify the other instances when an entity has changed. To cover this, the service broadcasts a cache clearing event (e.g. cache.clean.posts ) and also subscribes to this event. In the subscription handler, it calls the
broker.cacher.clean method. So if you have multiple instances of the service, and the first instance updates an entity, then it broadcasts the cache clearing event. Both instances will receive the event and both will clear the cache entries. It's simple but works with any number of instances.

The service will do it for you if you define the dependencies of service and the cacheCleanOnDeps mixin option is true . In this case, the service subscribes to all cache clearing events of the dependencies.

Example with dependencies The service also subscribes to the cache.clean.users and cache.clean.comments events.

"cache.clean.comments",

"my.some.event"

Action

Method Event Description

create

{serviceName}.created
createMany createEntities {serviceName}.created

updateEntity

{serviceName}.updated

Sent after an entity has been updated.

{serviceName}.replaced

removeEntity

{serviceName}.removed

Sent after an entity has been deleted.

{serviceName}.cleared

Example: Let's say, you have a users service and a posts service. If a user is deleted, we should also delete the user's posts. users.service.js It's just a simple service, you don't have to set anything special.

module.exports = {
name: "users",
mixins: [DbService(/*...*/)],
settings: {
fields: {
id: { type: "string", primaryKey: true, columnName: "_id" },
name: { type: "string" },
email: { type: "email" }}}};

adapterConnectedadapterConnected(adapter: Adapter, hash: string, adapterOpts: object)

It is called when a new adapter is created and connected to the database. You can use it to create data tables or execute migrations.

}}}

Entity hooks

{

name: "posts",

// ...

}}}}

3. Set this scope as default scope.

// posts.service.js
module.exports = {
name: "posts",
mixins: [DbService({ adapter: "MongoDB" })],
settings: {
fields: {
id: { type: "string", primaryKey: true, columnName: "_id" }, title: { type: "string", required: true, min: 5 },
content: { type: "string", required: true },

Example

Steps for configuration : Define the getAdapterByContext method to generate adapter options for

each tenant.

Adapters

The adapter is a class that performs the database operations with NPM libraries. This project contains many built-in adapters.

There are few common methods for all type of driver such as mongo driver, mysql driver , Knex driver etc.

ods

get hasNestedFieldSupport

It's a getter that returns whether the adapter can handle nested objects & arrays or not.

Disconnect from the database. Don't call directly!

find
find(params: object)

Find an entity based on the primary key.

findByIds
findByIds(id: Array<any>)

Count entities by params . The params contains the same properties as .

insert
insert(entity: object)

Update an entity by ID. The changes contains the changed properties of the entity. It returns the updated entity. If the adapter supports the raw changes, you can enable it with opts.raw = true . In this case,
the changes is not manipulated but passed directly to the database client.

updateMany
updateMany(query: object, changes: object, opts: object)

removeById
removeById(id: any)

Remove an entity by ID. It returns the removed entity ID.

Clear (truncate) the entire table/collection. It returns the number of entities removed.

entityToJSON
entityToJSON(entity: object)

Remove an index from the table/collection. .

MongoDB adapter(This section is specific to MongDB)

Usage

Use the default localhost URI

Options

const row = await this.updateEntity(ctx, {
id: "YVdnh5oQCyEIRja0",

$set: {
status: false,
height: 192
},
$inc: {
age: 1
},
$unset: {
dob: true
}
}, { raw: true });

objectIDToString

objectIDToString(id: ObjectID): String

Copyright © 2009-2023 UrgentHomework.com, All right reserved.