devinivy / bedwetter Goto Github PK
View Code? Open in Web Editor NEWAuto-generated, RESTful, CRUDdy route handlers for Waterline models in hapi
Auto-generated, RESTful, CRUDdy route handlers for Waterline models in hapi
If you are not aware yet, Hapi v17 is making the transition from callbacks to async
/await
, as well as deprecating some other rarely used functionality. This is a breaking change that may make your plugin no longer compatible with the Hapi API.
Draft release notes can be found here: hapijs/hapi#3658
The target release date for v17 is the beginning of November.
async
/await
compatible using the v17
branch from Hapi for testing
npm link
within the Hapi reponpm link hapi
within your plugin repov17
of Hapi branch for testsnpm
. Please use a major version increment as this will be a breaking change and it would be terrible for it to sneak into current versions of Hapi.<8.0.0
.v16
will continue to be supported for as long as there exists a Node LTS actively being supported that is not compatible with v17
.I have entities events
and eventlinks
. An event
can have multiple eventlinks
. And, eventlinks
are tied to linktypes
. populate: true
is set on all GET
routes.
Defined in the models as:
events.js
eventlinks: {
collection: 'eventlink',
via: 'event'
}
and
eventlinks.js
event: {
columnName: 'eventId',
model : 'event'
},
linkType: {
columnName: 'linkTypeId',
model: 'linktype',
populate: true
},
When i call the endpoint /api/eventlinks/1
, I get the details of the linktype
in the response payload:
{
"event": {
"eventDateTime": "2016-07-09T17:21:52.000Z",
"id": 1,
"eventType": 1,
"organisation": 1,
},
"linkType": {
"title": "customer",
"createdAt": null,
"updatedAt": null,
"id": 1,
"brand": 1
},
"createdAt": "2016-07-09T17:31:25.000Z",
"updatedAt": "2016-07-09T17:31:25.000Z",
"id": 1,
}
But, when I call the endpoint /api/events/1
, which will include all the eventlinks
, it only shows the id for the linkType
:
{
"eventlinks": [
{
"createdAt": "2016-07-09T17:31:25.000Z",
"updatedAt": "2016-07-09T17:31:25.000Z",
"id": 1,
"event": 1,
"linkType": 1
},
{
"createdAt": "2016-07-09T17:31:43.000Z",
"updatedAt": "2016-07-09T17:31:43.000Z",
"id": 2,
"event": 1,
"linkType": 2
},
{
"createdAt": "2016-07-09T17:32:06.000Z",
"updatedAt": "2016-07-09T17:32:06.000Z",
"id": 3,
"event": 1,
"linkType": 5
},
{
"createdAt": "2016-07-09T17:32:17.000Z",
"updatedAt": "2016-07-09T17:32:17.000Z",
"id": 4,
"event": 1,
"linkType": 6
}
],
"eventType": {
"title": "customer call",
"createdAt": null,
"updatedAt": null,
"id": 1
},
"createdAt": "2016-07-09T17:21:52.000Z",
"updatedAt": "2016-07-09T17:21:52.000Z",
"id": 1
}
Is this by design?
// TODO: set location for this item if possible.
return reply(asyncResults.actualChild).created(/* Location info goes here */);
When specifying a criteria blacklist, query params limit
, skip
, sort
, omit
etc., are no longer omitted from the criteria.
For example, here the childPk
is a string if it comes from the path parameter. The where criteria then fails! If where
is provided as a non-object (JUST the string/integer), all records are returned. That's what currently happens.
var childPk = parseInt(actionUtil.parsePk(request, options, true));
var where = childPk ? {id: childPk} : actionUtil.parseCriteria(request, options);
Model
.findOne(parentPk)
.populate(relation, {
where: where,
skip: actionUtil.parseSkip(request, options),
limit: actionUtil.parseLimit(request, options),
sort: actionUtil.parseSort(request, options)
})
Prefixing should be achieved using hapi's server.register
prefix option. The id
option is just a confusing, unnecessary feature.
Normalize options a bit. Let options interact with each other then settle down. For example, requireOwner
should perhaps be set to false
if actAsUser
is false
. Then we wont have to always check, for example options.actAsUser && options.requireOwner
. We could just check options.requireOwner
.
Also, use Joi to validate the options.
Allows a user to act on behalf of herself.
E.g., /users/10/follow/2
becomes /i/follow/2
.
Also allows potential implementation of document ownership. A user can only update an item if he owns it.
Allow hapi route prerequisite to handle request as a bedwetter. Dynamic handler generation. Or perhaps mirror request from web server to api server via route prerequisites. This would allow nice cohesion between web/api development. Would make bedwetter reusable in non-api web apps.
My app fails when I set up a route like the following:
module.exports = [
{
method: 'GET',
path: `api/users/{id}`,
config: {
handler: {
bedwetter: {}
}
}
}
]
If I change the line bedwetter: {}
with a reference to a function, it works. But, then I obviously loose the bedwetter functionality.
I suspect this might be because of the version of hapi
(13.0)/dogwater
(2.0) that I'm using. Or, am I missing something else?
Currently soft delete options just perform an update on a deleted flag. When soft delete is being used, one should be able to block reads/writes to soft-deleted records. This would require,
find
and findOne
.update
.add
and remove
if primary record or child record are soft-deleted.populate
if primary record or child record are soft-deleted.Bedwetter isn't reflecting the newly created association correctly.
Newly created comment from request.response.source
:
{ body: 'Hey @don-moe check out this trixel!',
owner: 1,
createdAt: Mon Jun 01 2015 13:57:44 GMT-0400 (EDT),
updatedAt: Mon Jun 01 2015 13:57:44 GMT-0400 (EDT),
id: 6 }
It is missing a trixel field. Bedwetter seems to be returning a stale version for the record.
When setting populate: true
to a GET
route, the response payload includes the attributes of the associated entities. This does, however, does not work for PUT
or PATCH
. Is there anyway to achieve this currently?
See outmoded/hapi-contrib#31. Also look into using items over async, hoek over lodash.
I have defined the following routes for an entity:
{
method: 'GET',
path: `${process.env.ENDPOINT_PREFIX_API_CSQA}/brands`,
config: {
handler: {
bedwetter: {
model: 'brand',
populate: true
}
},
auth: false
}
},
{
method: 'GET',
path: `${process.env.ENDPOINT_PREFIX_API_CSQA}/brands/{id}`,
config: {
handler: {
bedwetter: {
model: 'brand',
populate: true
}
},
auth: false
}
},
{
method: 'PUT',
path: `${process.env.ENDPOINT_PREFIX_API_CSQA}/brands/{id}`,
config: {
handler: {
bedwetter: {
model: 'brand'
}
},
auth: false
}
},
{
method: 'POST',
path: `${process.env.ENDPOINT_PREFIX_API_CSQA}/brands`,
config: {
handler: {
bedwetter: {
model: 'brand'
}
},
auth: false
}
},
{
method: 'DELETE',
path: `${process.env.ENDPOINT_PREFIX_API_CSQA}/brands/{id}`,
config: {
handler: {
bedwetter: {
model: 'brand'
}
},
auth: false
}
}
And, here's the model definition:
'user strict';
module.exports = {
identity: 'brand',
connection: 'dbCSQA',
tableName: 'Brand',
migrate: 'safe',
autoPK: false,
autoCreatedAt: 'createdAt',
autoUpdatedAt: 'updatedAt',
attributes: {
id: {
columnName: 'brandId',
type: 'integer',
primaryKey: true,
autoIncrement: true,
unique: true
},
brandName: {
type : 'string',
required : true,
unique: true,
maxLength: 50
},
brandAssetAbbr: {
type : 'string',
required : true,
unique: true,
maxLength: 5
}
}
}
All the routes work 100%, except when I add in the PUT
route, the server does not startup.
Write test for the bug this commit addresses in 1.1.0: f4cc718.
If userUrlPrefix was /user and the userModel was /users (per defaults), normalizing path would result in checking /user/users, which would fail.
Explain how these options extend functionality of ownerAttr
and childOwnerAttr
. Also, write tests.
If I have two entity models as follows:
module.exports = {
identity: 'assessment',
attributes: {
id: {
columnName: 'assessmentId',
type: 'integer',
primaryKey: true,
autoIncrement: true,
unique: true
},
questionnaire: {
columnName: 'questionnaireId',
model: 'questionnaire'
}
}
module.exports = {
identity: 'questionnaire',
attributes: {
id: {
columnName: 'questionnaireId',
type: 'integer',
primaryKey: true,
autoIncrement: true,
unique: true
},
title: {
type : 'string',
required: true,
maxLength: 100
},
assessments: {
collection: 'assessment',
via: 'questionnaire'
}
}
}
I can use the route GET /api/csqa/assessments?questionnaire=1
to get all assessments
link to questionnaire
1.
Butt, how would I specify the inverse. i.e. getting all questionnaires
used by assessment
1?
E.g. I'd like to require a user have a flag set for DELETE to take place. Note, response payload can be checked and scrubbed in hapi response validation or the postHandler extension.
See the dogwater milestone: https://github.com/devinivy/dogwater/milestones/1.0.0. This means we'll drop support for hapi7.
I need to emit a socketIO event when certain bedwetter handler routes finish successfully(no Boom errors).
Bedwetter registers itself as a handler and I can't seem to find a nice way to do a post-handler action.
What would be nice is if bedwetter provides some sort of a post handler hook or alternatively allow bedwetter to be executed as one of the pre-handler functions.
For the time being I can perhaps use the 'onPostHandler' extension point and look for successful routes but that doesn't seem like the best solution. Is there a better way ?
Related: #15.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.