API stands for Application Programming Interface. APIs allow the creation of an application to access features of an application or service. Building APIs with Node is very easy. Yes, you heard me right!
In this tutorial, you will be building a To-Do API. After you are done here, you can go ahead to build a front end that consumes the API, or you could even make a mobile application. Whichever you prefer, it is completely fine.
Application Setup
To follow this tutorial, you must have Node and NPM installed on your machine.
Mac users can make use of the command below to install Node.
brew install node
Windows users can hop over to the Node.js download page to download the Node installer.
Ubuntu users can use the commands below:
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs
To show that you have Node installed open your terminal and run node -v
. You should get a prompt telling you the version of Node you have installed.
You do not have not install NPM; it comes with Node. To prove that, run npm
-v
from your terminal and you will see the version you have installed.
Now go and create a directory where you will be working from, and navigate into it.
mkdir node-todo-api cd node-todo-api
Initialize npm in the current working directory by running:
npm init -y
The -y
flag tells npm to initialize using the default options.
That will create a package.json file for you. It is time to start downloading all the packages you will make use of. NPM makes this hassle free. You need them as dependencies.
To download these packages, run:
npm install express body-parser lodash mongoose mongodb --save
The --save
flag tells npm to install the packages as dependencies for your application.
When you open your package.json file, you will see what I have below:
#package.json "dependencies": { "body-parser": "^1.17.2", "express": "^4.15.3", "lodash": "^4.17.4", "mongodb": "^2.2.29", "mongoose": "^4.11.1" },
Before you start coding, you have to install MongoDB on your machine if you have not done that already. Here is a standard guide to help you in that area. Do not forget to return here when you are done.
Create the Todo Model
Create a folder called server, and inside it create another folder called models. This is where your Todo
model will exist. This model will show how your Todo collection should be structured.
#server/models/todo.js const mongoose = require('mongoose') // 1 const Todo = mongoose.model('Todo', { // 2 title: { // 3 type: String, required: true, minlength: 1, trim: true }, completed: { // 4 type: Boolean, default: false }, completedAt: { // 5 type: Number, default: null } }) module.exports = {Todo} // 6
- You need to require the mongoose package you installed using NPM.
- You create a new model by calling the model function of mongoose. The function receives two parameters: the name of the model as a string, and an object which contains the fields of the model. This is saved in a variable called
Todo
. - You create a text field for your to-do. The type here is String, and the minimum length is set at 1. You make it required so that no to-do record can be created without it. The trim option ensures that there are no white spaces when records are saved.
- You create a field to save true of false value for each to-do you create. The default value is false.
- Another field is created to save when the to-do is completed, and the default value is null.
- You export the
Todo
module so it can be required in another file.
Set Up Mongoose
Inside your server folder, create another folder called db and a file called mongoose.js.
This file will be used to interact with your MongoDB, using Mongoose. Make it look like this.
#server/db/mongoose.js const mongoose = require('mongoose') // 1 mongoose.Promise = global.Promise // 2 mongoose.connect(process.env.MONGODB_URI) // 3 module.exports = {mongoose} // 4
- You require the mongoose package you installed.
- Plugs in an ES6-style promise library.
- You call the connect method on mongoose, passing in the link to your MongoDB database. (You will set that up soon.)
- You export mongoose as a module.
Set Up the Configuration
Time to set up a few configurations for your API. The configuration you will set up here will be for your development and test environment (you will see how to test your API).
#server/config/config.js let env = process.env.NODE_ENV || 'development' // 1 if (env === 'development') { // 2 process.env.PORT = 3000 process.env.MONGODB_URI = 'mongodb://localhost:27017/TodoApp' } else if (env === 'test') { // 3 process.env.PORT = 3000 process.env.MONGODB_URI = 'mongodb://localhost:27017/TodoAppTest' }
- You create a variable and store it in the Node environment or the string development.
- The if block checks if env equals development. When it does, the port is set to 3000, and the MongoDB URI is set to a particular database collection.
- If the first condition evaluates to false and this is true, the port is set to 3000, and a different MongoDB database collection is used.
Create End Points
#server/server.js require('./config/config') // 1 const _ = require('lodash') // 2 const express = require('express') // 3 const bodyParser = require('body-parser') // 4 const {ObjectId} = require('mongodb') // 5 const {mongoose} = require('./db/mongoose') // 6 const {Todo} = require('./models/todo') // 7 const app = express() // 8 const port = process.env.PORT || 3000 // 9 app.use(bodyParser.json()) // 10 app.post('/todos', (req, res) => { let todo = new Todo({ text: req.body.text }) todo.save().then((doc) => { res.send(doc) }, (e) => { res.status(400).send(e) }) })
- Requires the configuration file created earlier.
- Requires lodash installed with NPM.
- Requires express installed with NPM.
- Requires bodyParser package.
- Requires ObjectId from MongoDB.
- Requires the mongoose module you created.
- Requires your
Todo
model. - Sets app to the express module imported.
- Sets port to the port of the environment where the application will run or port 3000.
- Sets up middleware to make use of bodyparser.
In the next part, you created the post request, passing in the path and a callback function which has request and response as its parameters.
In the block of code, you set todo
to the text that is passed in the body of the request, and then call the save function on the todo. When the todo is saved, you send the HTTP response—this time, the todo. Otherwise, the status code 400 is sent, indicating an error occurred.
#server.js ... // GET HTTP request is called on /todos path app.get('/todos', (req, res) => { // Calls find function on Todo Todo.find().then((todos) => { // Responds with all todos, as an object res.send({todos}) // In case of an error }, (e) => { // Responds with status code of 400 res.status(400).send(e) }) }) // GET HTTP request is called to retrieve individual todos app.get('/todos/:id', (req, res) => { // Obtain the id of the todo which is stored in the req.params.id let id = req.params.id // Validates id if (!ObjectId.isValid(id)) { // Returns 400 error and error message when id is not valid return res.status(404).send('ID is not valid') } // Query db using findById by passing in the id retrieve Todo.findById(id).then((todo) => { // If no todo is found with that id, an error is sent if (!todo) { return res.status(404).send() } // Else the todo retrieve from the DB is sent. res.send({todo}) // Error handler to catch and send error }).catch((e) => { res.status(400).send() }) }) // HTTP DELETE request routed to /todos/:id app.delete('/todos/:id', (req, res) => { // Obtain the id of the todo which is stored in the req.params.id let id = req.params.id // Validates id if (!ObjectId.isValid(id)) { // Returns 400 error and error message when id is not valid return res.status(404).send() } // Finds todo with the retrieved id, and removes it Todo.findByIdAndRemove(id).then((todo) => { // If no todo is found with that id, an error is sent if (!todo) { return res.status(404).send() } // Responds with todo res.send({todo}) // Error handler to catch and send error }).catch((e) => { res.status(400).send() }) }) // HTTP PATCH requested routed to /todos/:id app.patch('/todos/:id', (req, res) => { // Obtain the id of the todo which is stored in the req.params.id let id = req.params.id // Creates an object called body of the picked values (text and completed), from the response gotten let body = _.pick(req.body, ['text', 'completed']) // Validates id if (!ObjectId.isValid(id)) { // Returns 400 error and error message when id is not valid return res.status(404).send() } // Checks if body.completed is boolean, and if it is set if (_.isBoolean(body.completed) && body.completed) { // Sets body.completedAt to the current time body.completedAt = new Date().getTime() } else { // Else body.completed is set to false and body.completedAt is null body.completed = false body.completedAt = null } // Finds a todo with id that matches the retrieved id. // Sets the body of the retrieved id to a new one Todo.findOneAndUpdate(id, {$set: body}, {new: true}).then((todo) => { // If no todo is found with that id, an error is sent if (!todo) { return res.status(404).send() } // Responds with todo res.send({todo}) // Error handler to catch and send error }).catch((e) => { res.status(400).send() }) }) // Listens for connection on the given port app.listen(port, () => { console.log(`Starting on port ${port}`) }) // Exports the module as app. module.exports = {app}
You have created HTTP methods covering all parts of your API. Now your API is ready to be tested. You can do test it using Postman. If you do not have Postman installed on your machine already, go ahead and get it from the Postman website.
Start up your node server using node server.js
Open up postman and send an HTTP POST request. The specified URL should be http://locahost:3000/todos.
For the body, you can use this:
{ "text": "Write more code", "completed" : "false" }
And you should get a response. Go ahead and play around with it.
Conclusion
In this tutorial, you learned how to build an API using Node. You made use of a lot of resources to make the API a powerful one. You implemented the necessary HTTP methods that are needed for CRUD operation.
JavaScript has become one of the de facto languages of working on the web. It’s not without its learning curves, and there are plenty of frameworks and libraries to keep you busy, as well. If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato marketplace.
As you continue to build in Node, you will get to understand its power and the reason why it is used worldwide.
Powered by WPeMatico