Custom handler implementation #3

Closed
opened 2016-06-05 17:28:35 +00:00 by Istar-Eldritch · 13 comments
Istar-Eldritch commented 2016-06-05 17:28:35 +00:00 (Migrated from github.com)

So I was thinking on using this in one of the projects I am working on. Given our requirements, I would have to add some extra features.

The first of it is related with custom serializers. We plan to port the project in the future to jsonapi and I am also aware that in some situations people want to format the endpoints in a way that makes easier the frontend implementation.

The first idea I had was to make use of some functional composition. Allowing the developers to add to the options a map function that would let them change the format of the reply.

Let me know if is something of interest.

So I was thinking on using this in one of the projects I am working on. Given our requirements, I would have to add some extra features. The first of it is related with custom serializers. We plan to port the project in the future to [jsonapi](http://jsonapi.org/) and I am also aware that in some situations people want to format the endpoints in a way that makes easier the frontend implementation. The first idea I had was to make use of some functional composition. Allowing the developers to add to the options a map function that would let them change the format of the reply. Let me know if is something of interest.
mdibaiee commented 2016-06-05 17:45:20 +00:00 (Migrated from github.com)

Good idea for sure, what do you think about the modifier implementation described here?

This way the developer can modify the input and output of a function, along with an optional middleware.

I'm not sure what action we're going to modify using middlewares here though, ideas?

Good idea for sure, what do you think about the modifier implementation described [here](https://mdibaiee.gitbooks.io/slackbot-api/content/Documentation/modifiers.html)? This way the developer can modify the input and output of a function, along with an optional middleware. I'm not sure what action we're going to modify using middlewares here though, ideas?
Istar-Eldritch commented 2016-06-05 18:35:39 +00:00 (Migrated from github.com)

I think we can use the before and after create, read, update and delete actions.
The before hooks would allow for parsing payloads and url parameters from the request.
The after actions would allow for mapping the sequelize responses.

Maybe is a premature optimization but allowing the developer to specify the models in which those middleware should run when defining them will improve the runtime performance and the overall implementation. (As they won't need to check which model triggered the action)

The options object could receive an array of objects defining the middleware like:

{
  action: 'create',
  model: 'User',
  preprocess: function(req) {return {} },
  postprocess: function(sequelizeOutput) { return modifiedReply }
}

If some of the fields are not specified the library should provide default implementations. At the same the ones that appear first in the array should override the behaviour of the remaining.

This is just a draft idea, so don't hesitate to throw it away and propose something that would fit this better.😃

I think we can use the before and after create, read, update and delete actions. The before hooks would allow for parsing payloads and url parameters from the request. The after actions would allow for mapping the sequelize responses. Maybe is a premature optimization but allowing the developer to specify the models in which those middleware should run when defining them will improve the runtime performance and the overall implementation. (As they won't need to check which model triggered the action) The options object could receive an array of objects defining the middleware like: ``` js { action: 'create', model: 'User', preprocess: function(req) {return {} }, postprocess: function(sequelizeOutput) { return modifiedReply } } ``` If some of the fields are not specified the library should provide default implementations. At the same the ones that appear first in the array should override the behaviour of the remaining. This is just a draft idea, so don't hesitate to throw it away and propose something that would fit this better.😃
Istar-Eldritch commented 2016-06-05 18:42:08 +00:00 (Migrated from github.com)

One thing I left in the previous one:

the pre and post function should be maybe like this:

function(req, resp, next) {

}

So the user can interrupt the flow or do async tasks.

One thing I left in the previous one: the pre and post function should be maybe like this: ``` js function(req, resp, next) { } ``` So the user can interrupt the flow or do async tasks.
mdibaiee commented 2016-06-05 18:52:07 +00:00 (Migrated from github.com)

Yeah, the plan looks good.

I would suggest using Promises instead of next, or maybe we can have both.
The new ES version are praising Promises by introducing async/await, so I think that's a good way to go.

Yeah, the plan looks good. I would suggest using Promises instead of `next`, or maybe we can have both. The new ES version are praising Promises by introducing `async/await`, so I think that's a good way to go.
Istar-Eldritch commented 2016-06-05 18:56:44 +00:00 (Migrated from github.com)

Yep, that was my idea. If the developer returns a promise we use it. Note that async/await are es7 features not widely used at the moment.

Once you give green light I'll start working on a first PR ;)

Yep, that was my idea. If the developer returns a promise we use it. Note that `async/await` are es7 features not widely used at the moment. Once you give green light I'll start working on a first PR ;)
mdibaiee commented 2016-06-05 19:06:40 +00:00 (Migrated from github.com)

@Istar-Eldritch I'm asking my colleagues to review the idea to see if there are any flaws / any room for improvement, will notify you about it. Thank you Ruben! 🙏

@Istar-Eldritch I'm asking my colleagues to review the idea to see if there are any flaws / any room for improvement, will notify you about it. Thank you Ruben! :pray:
Istar-Eldritch commented 2016-06-05 19:07:32 +00:00 (Migrated from github.com)

@mdibaiee Sure! Take the time you need, there's no rush. 😉

@mdibaiee Sure! Take the time you need, there's no rush. 😉
mdibaiee commented 2016-06-17 10:33:47 +00:00 (Migrated from github.com)

Sorry for the long delay! 🙏

I think this is okay and we can proceed! Thank you Ruben!

Sorry for the long delay! :pray: I think this is okay and we can proceed! Thank you Ruben!
joeybaker commented 2016-09-14 02:45:52 +00:00 (Migrated from github.com)

@Istar-Eldritch FYI: I recently encountered a similar problem and solved it using standard Hapi settings. I added what I learned to the docs: https://github.com/mdibaiee/hapi-sequelize-crud/tree/master#modify-the-response-format

@Istar-Eldritch FYI: I recently encountered a similar problem and solved it using standard Hapi settings. I added what I learned to the docs: https://github.com/mdibaiee/hapi-sequelize-crud/tree/master#modify-the-response-format
joeybaker commented 2016-09-20 04:48:11 +00:00 (Migrated from github.com)

@Istar-Eldritch I just ran into the problem where I needed a "pre" hook and sorted it out with built-in hapi methods. I've added what I learned to the docs and closed this issue. Feel free to re-open if needed!

@Istar-Eldritch I just ran into the problem where I needed a "pre" hook and sorted it out with built-in hapi methods. I've added what I learned to the docs and closed this issue. Feel free to re-open if needed!
Istar-Eldritch commented 2016-09-20 09:04:03 +00:00 (Migrated from github.com)

@joeybaker Looks good to me.
Sorry for not replying before.

You may be interested as well in the default event lifecycle builtin hapi. Adding a onPostHandler or onPreResponse may provider extra functionality than the schema. You can see the whole hapi lifecycle here

If you set a tag in the route settings you are able to identify this route from all the handlers checking if the tag exists in req.route.settings.tags. This is the method I was using to achieve this. So was able to transform the data in ways the schema does not allow like changing the structure or decorating it with extra information.

@joeybaker Looks good to me. Sorry for not replying before. You may be interested as well in the default event lifecycle builtin hapi. Adding a `onPostHandler` or `onPreResponse` may provider extra functionality than the schema. You can see the whole hapi lifecycle [here](http://hapijs.com/api#request-lifecycle) If you set a tag in the route settings you are able to identify this route from all the handlers checking if the tag exists in `req.route.settings.tags`. This is the method I was using to achieve this. So was able to transform the data in ways the schema does not allow like changing the structure or decorating it with extra information.
Istar-Eldritch commented 2016-09-20 09:17:02 +00:00 (Migrated from github.com)

Ok, just found you have an entry as well for this in the main README.

Ok, just found you have an entry as well for this in the main README.
joeybaker commented 2016-09-20 12:55:55 +00:00 (Migrated from github.com)

Yup! Sorry for not linking to it before!

Yup! Sorry for not linking to it before!
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: thereadme/hapi-sequelize-crud#3
No description provided.