An Express/Node.js based server designed to be a “model agnostic” REST API server, which can perform CRUD operations on any data model
We’re opening a online store! In order to support our web application, we need to create an API that will serve specific data (namely, categories and products) to our application. We will write an API to interface with our databases to provide category and product information to our front end app.
As it is highly likely that we will need more data types and sources in the future, it’s imperative that we build this API as a standardized means of working with any data model, using any persistence system, though a common interface. The API Server must operate as follows:
i.e. http://amazingapi.com/api/v1/products/12345
/api/v#
where # is the version number of our API
/model
where ‘model’ is the name of the data model to operate on
/id
where ‘id’ is the id number of a specific entity in the data modelhttp://amazingapi.com/api/v1/products?category=electronics
application/json
GET MANY: http://amazingapi.com/api/v1/products
or http://amazingapi.com/api/v1.products?category=electronics
{
count: 300,
previous: null,
next: http://amazingapi.com/api/v1/products?page=2
results: [
{ name: 'camera', ... },
{ name: 'phone', ... },
{ name: 'tv', ... },
...
]
}
GET ONE: http://amazingapi.com/api/v1/products/12345
{
id: 12345,
name: 'camera',
manufacturer: 'Nikon',
model: 'xx435',
price: 99.99,
inStock: 2200,
weight: 1.1
}
POST: http://amazingapi.com/api/v1/products
Create requires that you POST a JSON object to the route that corresponds to the correct model (products, in this case) and returns an object representing what you created:
Request Body:
{
id: 12345,
name: 'camera',
manufacturer: 'Nikon',
model: 'xx435',
price: 99.99,
inStock: 2200,
weight: 1.1
}
Output
{
id: 12345,
name: 'camera',
manufacturer: 'Nikon',
model: 'xx435',
price: 99.99,
inStock: 2200,
weight: 1.1
}
PUT or PATCH: http://amazingapi.com/api/v1/products/12345
Updating records with PUT or PATCH requires a JSON object be given to a route that specifies both the model name and the record ID that represents the record you wish to update. The object given to the route is to be either the FULL object in the case of a PUT, or just the fields you wish to modify, in the case of a PATCH. These operations must always return the object as it exists in the data source after your update operation.
For example, to change the price:
PUT Request Body:
{
id: 12345,
name: 'camera',
manufacturer: 'Nikon',
model: 'xx435',
price: 109.99,
inStock: 2200,
weight: 1.1
}
Output:
{
id: 12345,
name: 'camera',
manufacturer: 'Nikon',
model: 'xx435',
price: 109.99,
inStock: 2200,
weight: 1.1
}
PATCH Request Body:
{
price: 109.99,
}
Output:
{
id: 12345,
name: 'camera',
manufacturer: 'Nikon',
model: 'xx435',
price: 109.99,
inStock: 2200,
weight: 1.1
}
DELETE: http://amazingapi.com/api/v1/products/12345
This operation should remove the record with the given ID (12345) from the model (products). The return should be the state of that record in the database following the operation. Convention dictates an empty object be returned rather than null
.
Sample Output:
{}
The application will be created with the following overall architecture and methodologies
require()
the correct module model (i.e. if the model is categories, require('src/models/categories/categories-model.js')
)v1.js
) to handle the ReST methods for CRUD for any model
express.params
middlewaresupergoose
to:
As we will be operating a virtual storefront, this application requires 2 data models to be fully functional
The following fields/data types must be supported by your data model
├── .gitignore
├── .eslintrc.json
├── __tests__
│ ├── v1.test.js
│ ├── 404.test.js
│ ├── 500.test.js
│ ├── model-finder.test.js
│ ├── mongo.js
├── lib
│ ├── api
│ │ ├── v1.js
│ ├── middleware
│ │ ├── 404.js
│ │ ├── 500.js
│ │ ├── model-finder.js
│ ├── models
│ │ ├── mongo.js
│ │ ├── categories
│ │ │ ├── categories-model.js
│ │ │ ├── categories-schema.js
│ │ ├── products
│ │ │ ├── products-model.js
│ │ │ ├── products-schema.js
│ ├── server.js
├── index.js
└── package.json
app.get('/api/v1/categories')
and app.get('/api/v1/products')
with app.get('/api/v1/:model')