Google Datastore Entities Modeling for Node.js
Virtual properties that you declare on the Schema are now directly accesible on the entity instance. If you change a virtual property on the instance, it updates the entityData directly.
See the doc: https://sebelga.gitbooks.io/gstore-node/content/schema/schema-methods/virtual.html
The global gstore.save()
method has now an optional configuration object with 2 properties
validate
(default false) ---> Validate the entities before savingmethod
(default "upsert"} --> Datastore save method (insert, update or upsert)gstore-node has now a Type declaration file that should make development in Typescript much easier! Refer to the documentation to see how to add Typescript types to your Schemas.
The Schema properties types should be passed from now on as Javascript types.
// before
const schema = new Schema({
name: { type: 'string' },
age: { type: 'int' }
});
// after
const schema = new Schema({
name: { type: String },
age: { type: Number }
});
The old format is still supported but will be deprecated in future release.
gstore.errors.codes.ERR_ENTITY_NOT_FOUND
codegstore fully integrates gstore-cache to speed up your entities fetching by providing and advanced cache layer. Read the documentation to see how easy it is to setup.
gstore has a helper to create a Dataloader instance that works with the Datastore. Read the documentation for all the information.
The Model.get() and Model.update()
methods accept a Dataloader instance to optimize the entity fetching.
A change has been made in the "promised-hooks" dependency to change an undesired behavior in the "hooks". Previously if a hook returned a value, it would override the arguments of the wrapped method. As it is only useful in some edge cases (during a migration of data maybe), this behavior has been removed.
Now the "pre" and "post" middleware response is not taken into account unless you specify it by resolving with an object containing an "__override" property.
User.pre('delete', yourMiddleware);
function yourMiddleware() {
return new Promise((resolve, reject) => {
// ...
/**
* With the override below, the User.delete() method will
* receive those arguments instead of the one originally provided
*/
resolve({ __override: 123 }); // single argument
// or
resolve({ __override: [ 123, 'arg2' ] }); // multi arguments
});
}
Errors returned by "post" hooks are now added on a Symbol instead of the errorsPostHook property.
User.post('save', postMiddleware);
function postMiddleware() {
return new Promise((resolve, reject) => {
// call async service...
myApi.doSomething((err) => {
if (err) {
return reject(err);
}
return resolve();
});
});
}
// ...
// some-controler.js
const gstore = require('gstore-node')();
const User = require('./users/user.model');
const user = new User({ name: 'john' });
user.save().then((response) => {
// The save occurred without issue but
// we might need to know if there are any "post" hook error
if (response[gstore.ERR_HOOKS]) {
// deal with errors
}
...
});
The code returned when an entity is not found has been changed from 404
to gstore.codes.ERR_ENTITY_NOT_FOUND
.
You now can define your schemas with Joi types definition. Joi is an excelent schema description language packed with loads of utilities to validate Javascript objects.
See the doc for instructions on how to implement Joi validation in your schemas.
Validation has been updated to provide better error handling and messages. Each validation error has now an error code and type and the details of the errors after validation is now much clearer.
// before
const { success } = entity.validate();
//after
const { error } = entity.validate();
// error === null --> valid
You can now create several instances of gstore connecting to datastore with different namespace. In order to achieve this, you have to make a small change in the gstore initialisation
// before
const gstore = require('gstore-node');
// after
const gstore = require('gstore-node')();
If you need several instances on a different namespaces you can do
const setting = { namespace: 'com.mydomain' };
const setting2 = { namespace: 'com.mydomain.other' };
const gstore1 = require('gstore-node0')(setting);
const datastore1 = require('@google-cloud/datastore')(setting);
const gstore2 = require('gstore-node0')(setting2);
const datastore2 = require('@google-cloud/datastore')(setting2);
gstore.connect(datastore);
gstore2.connect(datastore2);
// then anywhere in your models/controllers
// you can require any of the instances
const gstore = require('gstore-node')({ namespace: 'com.mydomain.other' });