JKHeadley / rest-hapi

🚀 A RESTful API generator for Node.js
https://resthapi.com
MIT License
1.19k stars 153 forks source link

add functionality of Upsert #64

Open techloverparveen opened 6 years ago

techloverparveen commented 6 years ago

Hi, Sometime we want to update the document if that is already inserted otherwise we will insert a new one for this like mongo give us Upsert:true option, so suppose i am using Rest-Hapi then how can i achieve the same thing via Rest-Hapi, i mean is there a way to do this.

Thanks

JKHeadley commented 6 years ago

@parveen-oodles this feature is not currently supported, but will hopefully be added to a future version.

JKHeadley commented 6 years ago

I like the idea of creating a new PUT /model endpoint that mirrors the functionality of the mongoose findOneAndUpdate function. Basically the endpoint would accept a query filter (same as the GET /model endpoint) and the first document found would be updated. Also, an $upsert query param could be supported that would affect the behavior when a document is not found. If $upsert is set to false (default) then the endpoint would return a 404 error. If $upsert is set to true, then the payload would be inserted just like a call to POST /model.

NOTE: I still haven't thought through all the implications of this functionality, however there could be some complications. For instance, since $upsert: true can be equivalent to POST /model, we should probably consider applying the same restrictions (authorization, payload validation, etc) as the create/POST endpoint. This might be as simple as checking the $upsert param, and either passing the payload off to the update handler or the create handler. This way users could not bypass the POST /model restrictions through PUT /model and be able to add documents (or specific fields) when they shouldn't.

shiva commented 6 years ago

@JKHeadley I am starting work on this. Can you assign this to me? Starting with changes to handler-helper, and building up to supporting as described here.

shiva commented 6 years ago

Also, we can't simply pass the operation through, especially if the goal is to leverage findOneAndUpdate. All rest-hapi "features" i.e authorization/payload validation etc are performed orthogonal to the handler that is created in handler-helper. In addition, upsert requires "read", "create" and "update" privileges.

Option 1: If and only if all three authorization checks (ie. query, create and update) pass, upsert is allowed.

Option 2: introduce a new authorization class, and if that is enabled, user can upsert.

Option 3: Refactor create and other methods, so that authorization, validation and other functions are separated. Then we can re-combine them in upsert.

Any preferences? Did I read the code correctly?

shiva commented 6 years ago

First commit towards this is in! https://github.com/shiva/rest-hapi/tree/feature/upsert Feel free to provide comments.

JKHeadley commented 6 years ago

@shiva Thanks for jumping on this. Unfortunately I can't assign issues to non-collaborators.

You are correct, the best approach seems to be to create new upsert handler, factory functions, and validation functions.

As far as authorization goes, from a high level standpoint I would say the user should have to pass a read, update, and create check.

I don't think the user should be required to specify any extra config properties specific to upsert (besides possibly policies) since this would create loopholes where a user might be able to create or update a resource that they shouldn't have permissions to.

After going through the code again it looks like it will be quite a challenging task to perform appropriate update and create features, especially for the generation and enforcing of scopes.