Comments (6)
I am 100% on board with this approach and can envision an architecture that would facilitate this. I believe what we need are a few abstraction classes that would expose the "model" interface and then create classes that extend this interface. One of those classes would be the Mongoose model class, while the other would simply provide either in-memory manipulation or "virtual" restful capabilities.
Great idea and I am very supportive of your development of that feature.
Thanks for your help.
Travis.
from resourcejs.
I now have a working solution that I would like to run by you. Its solves my specific use-case and seems to be generally useful as a means of presenting virtual resources. I have attempted to re-use as much of the original resourcejs design features as I could to minimise the code impact and hopefully keep to the principle of least-surprise.
I have added a new pseudo-method called virtual
. As with the index
pseudo-method, the new virtual
method is based on the intrinsic get
method.
Given a concrete resource defined by a schema, one to many virtual
methods can be described by passing options to the resource.virtual
method and any of the other isomorphic techniques for defining a resourcejs method that is usual for the other methods - index
, get
etc.
The virtual
method further expects a new options parameter called name
to be provided. This will be used to generate the virtual-resource API end-point according to the following pattern:
/[resource-name]/virtual/[virtual-resource-name]
The shape of json data returned is determined by a before
function that is also passed as an options param. This function is expected to act on the concrete resource to return a virtual-resource of arbitrary shape. Typically I would expect this to be a mongodb aggregate function although any process supported by the mongoose model can be used here.
For example, given a resource called 'product' with the following schema
{Schema} = require 'mongoose'
schema: new Schema
name : String
price : Number
stock : Number
I can define a couple of aggregate functions called max-price
and max-stock
maxPrice = (req, res, next)->
req.modelQuery = @model
.aggregate()
.group _id:null, maxPrice:$max:'$price'
next()
maxStock = (req, res, next)->
req.modelQuery = @model
.aggregate()
.group _id:null, maxStock: $max:'$stock'
.select
next()
I then setup the product resource via resourcejs passing in the name and the aggregate functions in the options, for example:
product.virtual({name:'max-price', before:maxPrice})
product.virtual({name:'max-stock', before:maxStock})
product.get (etc...)
I can then retrieve the virtual resources using the following urls:
/product/virtual/max-price
returns {_id:null, maxPrice:123}
/product/virtual/max-stock
returns json {_id:null, maxStock:321}
My criticism of this approach is the need to insert the hard-coded /virtual/ url segment. I would prefer not to do this but using the more concise (and less surprising) url [resource-name]/[virtual-resource-name] caused conflicts with the existing get
by id
method. Can you suggest how to simplify the virtual
url structure without causing conflicts?
I hope that is clear. If this feels like an acceptable approach to you then I will issue a pull request so you can review the code.
Thanks
from resourcejs.
I like this approach. Why not define the path of the method during the registration process?
product.virtual({path: 'max', name:'max-stock', before:maxStock})
This allows you to define the path for the resource... this may seem somewhat redundant with the name
parameter so is there a reason the name
parameter could not be the path
to the virtual resource?
from resourcejs.
Good idea on re-using the path
options param. I will make that change.
This will still leave us with the url schema containing the hard-coded url element virtual
:
[resource-name]/virtual/[path]
Are you happy with this?
from resourcejs.
I have made the changes as requested and we can now use the options.path
param instead of the options.name
. There was some confusion as I had problems with corrupt idx files and had to re-fork. The pull request is #13
from resourcejs.
merged
from resourcejs.
Related Issues (20)
- can't get example in README.md to work HOT 2
- Is there an admin / documentation html-interface for resourcejs? HOT 1
- Return code 200 and empty array instead of error 500 on GET request for empty collection HOT 1
- Type definitions HOT 1
- Allow passing of options down to `save()` method HOT 1
- Add ability to pass options to Document.save()
- Why does `Resource.respond()` call `next()` at the end HOT 2
- Add documentation for `hooks`
- Should `before` and `before[method]` handlers be merged?
- Allow Population on `get()` request
- Allow complex population
- Document all the fields that can be set on `req` in before handlers
- `get()` passes `search` to before hook
- Can't see the swagger UI
- Unable to use get for all data inside my react state HOT 1
- Bug / Question: Virtual Resources
- The regex doesn't work as well
- Fast JSON patch needs to be updated. HOT 2
- How to add custom Error Handler?
- Support mongoose 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from resourcejs.