Security News
Internet Archive Hacked, 31 Million Record Compromised
The Internet Archive's "Wayback Machine" has been hacked and defaced, with 31 millions records compromised.
resource-schema
Advanced tools
Define schemas for RESTful resources from mongoose models, and generate middleware to GET, POST, PUT, and DELETE to those resources.
Define schemas for RESTful resources from mongoose models, and generate express middleware to GET, POST, PUT, and DELETE to those resources.
ResourceSchema allows you to define complex RESTful resources in a simple and declarative way.
schema = {
'_id': '_id'
# Get resource field 'name' from model field 'name'
# Convert the name to lowercase whenever saved
'name':
field: 'name'
set: (productResource) -> productResource.name.toLowerCase()
# make sure the day matches the specified format before saving
'day':
field: 'day'
match: /[0-9]{4}-[0-9]{2}-[0-9]{2}/
# Model field 'active' renamed to resource field 'isActive'
'isActive': 'active'
# Dynamically get field 'code' whenever the resource is requested:
'code':
get: (model) -> model.letter + model.number
# Dynamically get totalQuantitySold whenever the resource is requested.
# Resolve 'totalQuantitySoldByProductId' before applying the getter.
'totalQuantitySold':
resolve:
totalQuantitySoldByProductId: ({models}, done) ->
getTotalQuantitySoldById(models, done)
get: (productModel, {totalQuantitySoldByProductId}) ->
totalQuantitySoldByProductId[productModel._id]
}
queryParams =
# query for products sold on the specified days
# e.g. api/products?soldOn=2014-10-01&soldOn=2014-10-05
'soldOn':
type: String
isArray: true
match: /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/
find: (days) -> { 'day': $in: days }
# query for products sold in the last week
# e.g. api/products?fromLastWeek=true
'fromLastWeek':
type: Boolean
find: (days) -> { 'day': $gt: '2014-10-12' }
resource = ResourceSchema(Product, schema, {queryParams})
# generate express middleware that automatically handles GET, POST, PUT, and DELETE requests:
app.get '/products', resource.get(), resource.send
app.post '/products', resource.post(), resource.send
app.put 'products/:_id', resource.put('_id'), resource.send
app.get 'products/:_id', resource.get('_id'), resource.send
app.delete 'products/:_id', resource.delete('_id'), resource.send
This abstracts away a lot of the boilerplate such as building queries, validating values, and handling errors, and allows you to focus on higher-level resource design.
Once you have defined a new resource, call get, post, put, or delete to generate the appropriate middleware to handle the request.
resource = new ResourceSchema(Model, schema, options)
app.get '/products', resource.get(), (req, res, next) ->
# resources are on res.body
the middleware will attach the resources to res.body, which can then be used by other pieces of middleware, or sent immediately back to the client
Generate middleware to handle GET requests for multiple resources.
Generate middleware to handle POST requests to a resource.
Generate middleware to handle PUT requests to a resource.
Generate middleware to handle DELETE requests to a resource.
Convenience method for sending the resource back to the client.
resource = new ResourceSchema(Model, schema, options)
app.get '/products', resource.get(), resource.send
Maps a mongoose model field to a resource field.
schema = {
'name': { $field: 'name' }
}
We can also define this with a shorthand notation:
schema = {
'name': 'name'
}
Or even simpler with coffeescript:
schema = {
'name'
}
Note, this can be used to rename a model field to a new name on the resource:
schema = {
'category.name': 'categoryName'
}
# => {
# category: {
# name: 'value'
# }
# }
Dynamically get the value whenever a resource is requested. Note, you need to explicitly set the value on each resource
schema =
'fullName':
get: (resource, {req, res, next}) ->
resource.firtName + ' ' + resource.lastName
Dynamically set the value whenever a resource is saved or updated
schema = {
'name': {
set: (model, {req, res, next}) ->
model.name.toLowerCase()
}
}
Dynamically find resources with the provided query value. Return an object that will extend the mongoose query. $find is used to define query parameters.
schema = {
'soldOn': {
find: (days, {req, res, next}) ->
{ 'day': $in: days }
}
}
If true, do not include the value in the resource unless specifically requested by the client with the '$add' query parameter
# GET /api/products?$add=name
schema = {
'name': {
optional: true
field: 'name'
}
}
Return a 400 invalid request if the provided value does not pass the validation test.
schema = {
'date': {
validate: (value) ->
/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/.test(value)
}
}
Return a 400 invalid request if the provided value does match the given regular expression.
schema = {
'date': {
match: /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/
}
}
Convert the type of the value.
Valid types include
schema = {
'active': {
type: Boolean
}
}
This is especially useful for query parameters, which are a string by default
Ensure that the query parameter is an Array.
schema = {
'daysToSelect': {
isArray: Boolean
find: (days, context, done) -> ...
}
}
Set the default number of the resources that will be sent for GET requests.
new ResourceSchema(Product, schema, {
defaultLimit: 100
})
Set the default query for this resource. All other query parameters will extend this query.
new ResourceSchema(Product, schema, {
defaultQuery: {
active: true
createdAt: $gt: '2013-01-01'
}
})
Define query parameters for this resource using the $find method. Note that these query parameters can be defined directly on the schema, but you can define them here if you prefer (since query parameters are often not part of the resource being returned).
queryParams =
'soldOn':
type: String
isArray: true
match: /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/
find: (days) -> { 'day': $in: days }
'fromLastWeek':
type: Boolean
find: (days) -> { 'day': $gt: '2014-10-12' }
ResourceSchema automatically adds several utilities for interacting with your resources.
Query by any resource field with a $field or a $find attribute.
GET /products?name=strawberry
GET /products?categrory[name]=fruit
Note that you can query nested fields with Express' [bracket] notation.
Select fields to return on the resource. Similar to mongoose select.
GET /products?$select=name&$select=active
GET /products?$select[]=name&$select[]=active
GET /products?$select=name%20active
Limit the number of resources to return in the response
GET /products?$limit=10
Add an $optional field to the response. See $optional schema fields for more details.
GET /products?$add=quantitySold
List just the nested attributes you care about:
'user.name'
'user.email'
Or include the root attribute to include all nested attributes:
'user'
You can even add optional attributes:
'user'
'user.note':
optional: true
$ git clone https://github.com/goodeggs/resource-schema && cd resource-schema
$ npm install
$ npm test
Code of Conduct for contributing to or participating in this project.
FAQs
Define schemas for RESTful resources from mongoose models, and generate middleware to GET, POST, PUT, and DELETE to those resources.
The npm package resource-schema receives a total of 4 weekly downloads. As such, resource-schema popularity was classified as not popular.
We found that resource-schema demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Internet Archive's "Wayback Machine" has been hacked and defaced, with 31 millions records compromised.
Security News
TC39 is meeting in Tokyo this week and they have approved nearly a dozen proposals to advance to the next stages.
Security News
Our threat research team breaks down two malicious npm packages designed to exploit developer trust, steal your data, and destroy data on your machine.