Quickly build a blog api with QuickCrud.js
Tags: mongoose, quickcrud, quick
Published: 2020-04-25 18:02:04

---
title: Quickly build a blog api with QuickCrud.js
published: true
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/kxaf2i85a6odyhjp3rig.png
description: Mongoose is one of the best ORM so far for MongoDB. Their crud API is so good but we need to do a lot of repetitive tasks over and over in order to do pagination, sorting and populating. For reducing the pain of your neck, here comes the magical tool QuickCrud.js
tags: mongoose, quick-crud, quick
---

Mongoose is one of the best ORM so far for MongoDB. Their crud API is so good but we need to do a lot of repeated things over and over in order to do pagination, sorting and populating. For reducing the pain of your neck, here comes the magical tool QuickCrud.js

Let's quickly build a blog API with QuickCrud.js

## Setup Express



#### Step 1

**Install packages**
```bash
npm init -y

yarn add express mongoose quick-crud
```

#### Step 2

Let's setup express server via **index.js**

```js
const express = require('express')
const app = express()

// Body parser for accepting json from client
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

app.get('/', (req, res) => {
	res.json({
		message: 'QuickCrud.js blog api'
	})
})

// Connect to db via mongoose
mongoose
	.connect(/*db_url*/)
	.then(() => {
		console.log('Database Connected.')
	})
	.catch((error) => {
		console.log('Database Connect Faield.')
	})

// Start server
app.listen(3000, () => {
	console.log('server running on http://localhost:3000')
})

```

#### Step 3
Then we will create a directory named models and write 2 model files here.

**Post.js**
```js
const mongoose = require('mongoose')

const postSchema = new mongoose.Schema({
	title: String,
	body: String,
	categories: [
		// referencing the category model
		{
			type: mongoose.SchemaTypes.ObjectId,
			ref: 'Category'
		}
	]
})

const Post = mongoose.model('Post', postSchema)
module.exports = Post

```

**Category.js**
```js
const mongoose = require('mongoose')

const categorySchema = new mongoose.Schema({
	name: String
})

const Category = mongoose.model('Category', categorySchema)
module.exports = Category

```



#### Step 4
Create **routes** directory and put `posts.js` and `categories.js` on it. We will work with these two routes to illustrate QuickCrud.js


At first, let's create `posts.js` and `categories.js` base endpoints 


```js
// file: routes/posts.js
const Router = require('express').Router()

// Get post list
Router.get('/', (req, res) => {})

// Create a post
Router.post('/', (req, res) => {})

// Get a single post
Router.get('/:_id', (req, res) => {})

// Update a single post
Router.put('/:_id', (req, res) => {})

// Delete a post
Router.delete('/:_id', (req, res) => {})

module.exports = Router
```


```js
// file: routes/categories.js

const Router = require('express').Router()

// Get category list
Router.get('/', (req, res) => {})

// Create a category
Router.post('/', (req, res) => {})

// Get a single category
Router.get('/:_id', (req, res) => {})

// Update a single category
Router.put('/:_id', (req, res) => {})

// Delete a category
Router.delete('/:_id', (req, res) => {})

module.exports = Router

```

And the update our `index.js` file to hook up these routes

```js
const express = require('express')
const app = express()

// Body parser for accepting json from client
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

// Routes
app.use('posts', require('./routes/posts'))
app.use('categories', require('./routes/categories'))

app.get('/', (req, res) => {
	res.json({
		message: 'QuickCrud.js blog api'
	})
})

app.listen(3000, () => {
	console.log('server running on http://localhost:3000')
})
```


#### Step 5
Now let's start doing magic with `QuickCrud.js`. As we are using this magical tool, we no longer need any controller file for routes. We have all sorts of crud functionality on QuickCrud.js out of the box which we have to do repeatedly on controllers.

In QuickCrud.js have 5 methods
- index() - For fetching all resources with pagination and limiting
- store() - Create a document
- show() -  Fetch a single resource with schema key
- update() - Update an existing document
- destroy() - Delete an existing document


**Create category document**

```js
Route.post('/', async (req, res) => {
	const _doc = await qc.store(Category, req.body)
	res.json(_doc)
})
```

**Response**
```json
{
    "_id": "xxx",
    "name": "cat 1",
    "__v": 0
}
```


**Get All categories**

For getting all categories, we have `qc.index()` method.

```js
Route.get('/', async (req, res) => {
	const _docs = await qc.index(Category)
	res.json(_docs)
})
```

**Response**
![](https://dev-to-uploads.s3.amazonaws.com/i/q0nhe78ybu8rulzoxaav.jpg)


**Limiting and paginating with ?page and ?limit**
`qc.index()` method have 3 args: Model, Population, PagitionOption.

With `PagitionOption` of `qc.index()` we can do pagination and limiting resources list.

```js
Route.get('/', async (req, res) => {
	const _docs = await qc.index(Category, {} , {
		page: +req.query.page,
		limit: +req.query.limit
	})
	res.json(_docs)
})
```


**?limit=3&page=1**

![Page1](https://dev-to-uploads.s3.amazonaws.com/i/6dvl793oboqtvvcdrcba.jpg)

**?limit=3&page=2**
![Page2](https://dev-to-uploads.s3.amazonaws.com/i/qs51azha3hpu567ebgj9.jpg)



### Update and Delete category
Updating and deleting is pretty straight forward with `qc.destroy()` and `qc.update()`

```js
// Update a single category
Route.put('/:_id', async (req, res) => {
	let data = await qc.update(
		Category,
		{
			_id: req.params._id
		},
		req.body
	)

	res.json({
		message: 'Category updated',
		data
	})
})

// Delete a category
Route.delete('/:_id', (req, res) => {
	let data = await qc.destroy(Category, {
		_id: req.params._id
	})

	res.json({
		message: 'Category deleted',
		data
	})
})
```

<br/>
<br/>
<br/>

### Post endpoints
As like previous categories route, post's update and delete is dead simple and straight forward.

```js
// Update a single post
Router.put('/:_id', (req, res) => {
    let data = await qc.update(
        Post,
        {
            _id: req.params._id
        },
        req.body
    )

    res.json({
        message: 'Post updated',
        data
    })
})

// Delete a post
Router.delete('/:_id', (req, res) => {
    let data = await qc.destroy(Post, {
        _id: req.params._id
    })

    res.json({
        message: 'Post deleted',
        data
    })
})
```

**Lets create some posts with categories**

![create post](https://dev-to-uploads.s3.amazonaws.com/i/puwtmpslazri4t3qdjd8.jpg)

Now lets fetch all and single resource with categories population

```js
// Get post list
Router.get('/', async (req, res) => {
	const _docs = await qc.index(Post, {} , {
		page: +req.query.page,
		limit: +req.query.limit
	} , 'categories')
	res.json(_docs)
})

// Get a single post
Router.get('/:_id', async (req, res) => {
	const _docs = await qc.show(Post, { _id: req.params._id }, 'categories')
	res.json(_docs)
})
```


**Post list with categories population**
![Post list with categories population](https://dev-to-uploads.s3.amazonaws.com/i/ttxlmnpfy1f8ftjvuqpv.jpg)


**Single post with categories population**
![Single post with categories population](https://dev-to-uploads.s3.amazonaws.com/i/7w8g7aq39jrofvpk4olx.jpg)



Want to explore more?
Checkout package documentation: https://www.npmjs.com/package/node-crud


Feel free to report any type of bug report or feature request.
{% github kingRayhan/quick-crud %}

# [Source code](https://github.com/kingRayhan/quick-crud-blog)