Create your own CRUD API on Express and MySQL: part one

Hello everyone. In anticipation of the start of the “Fullstack JavaScript Developer” course , we want to share a little material that was written by our freelance writer.



Express is one of the most popular web frameworks that supports routing, middleweights and a template system. Doing a backend on Node.js without Express in 2020 is a rather strange activity, because Express is a de facto framework for building a web application on Node.js.
Today we will try to create a simple CRUD API using the MySQL database. An experienced Node.js reader will ask, where is MongoDB, with which Node.js are usually used in tandem, but I’ll say right away this article is more for PHP developers who want to touch Node.js a bit, and to mitigate the transition to a new ecosystem, we we will use MySQL. We’ll create an API for a simple Todo application, in case someone wants to attach to his todo (and it doesn’t matter whether it is written with React or not), attach a little back and play with it.


"Architecture" and the essence of our application



In our application it will be possible to create, receive, update and delete Todo. In general, we will have a minimal set of CRUD functions (create read update delete).

In the end, we will combine the application with the application on React and we will test everything.

First, I’ll give the structure of the application files:



Next, I’ll give a table of actions and methods that are in our application:

MethodsUrlActions
Get/ dealsgetting all the cases
Get/ deals / 2Getting id with number 2
Post/ dealsadding a new case
Put/ deals / 3Update user with id = 3
DELETE/ deals / 3delete user with id = 3
DELETE/ dealsremove all users

Creating Your Node.js Application

Go to your favorite directory, launch the terminal and create your application. By the way, it’s probably clear from the title that Node.js should already be installed. If you have not already done so, then this simply cannot be downloaded from the link from here.

    $ mkdir CRUD_API
    $ cd CRUD_API

Next, you need to initialize our application using npm init . Because our application is more of a test and training one, I will use a command that will fill in all the default data so as not to waste time on small details:

 npm init -y
 

If that, then with your hands in package.jsonyou can change the data to the one you need: the github repository, tags, author, etc.

Then we need to put all the packages necessary for the application to work:

  npm i express mysql body-parser --save


If you are going to send your development to github later, you should create a hidden file .gitignoreso as not to drag the heaviest node_modules and disgrace yourself . We write:

    touch .gitignore 
    code .gitignore 

We enter there node_modules, later in this file you can enter the names of folders and files that you want to see later on the remote server.

Basic Express setup


In the root folder of the project, create a file server.js:

    const express = require("express");
    const bodyParser = require("body-parser");
    
    const app = express();
    
    //     json
    app.use(bodyParser.json());
    
    //    : application/x-www-form-urlencoded
    app.use(bodyParser.urlencoded({ extended: true }));
    
    //   response - request
    app.get("/", (req, res) => {
      res.json({ message: "    " });
    });
    
    //  ,   
    app.listen(3001, () => {
      console.log("   3001 ");
    });

Now we can start the server with:

node server.js

We need Express to create our api, and the body-parser package helps us parse request and create req.bodyone that is useful for routing.

Now our server can do the following:

  • Create an Express app that renders body-parser a midlever using app.use ()
  • we have a simple get, just to test the application
  • Listen to port 3001 for all incoming changes

Initially, our application works, then you can do the database.

Create your MySQL data table

I really hope that the reader of this article has no problem downloading and installing MySQL and MySQLWorkBranch on their own. Next, you yourself create a scheme (DB) with the name that you like best (in my case, TODO), and then select the lightning request and copy / type the following command:

    CREATE TABLE IF NOT EXISTS `todo` (
        id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
        text varchar(255) NOT NULL
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

In our database, everything will be at a minimum: only id and the text of the case itself. However, to add another column in which, for example, the urgency of your case can be described, I hope that it will not cause problems.

Configuration & Connect with our database

Let's establish and configure the connection to the database. We will create a new app folder directly in our root folder, and there we will create a file db.config.jsin the folder config, with approximately the same content, which depends on your settings in MySQLWorkBranch. In my case, the file will look like this:

  module.exports = {
    HOST: "localhost",
    USER: "pavel",
    PASSWORD: "",
    DB: "TODO"
  };

After that, create a folder to describe our app / mode models , in which we will then create a model:

  const mysql = require("mysql");
  const dbConfig = require("../config/db.config.js");
  
  //      
  const connection = mysql.createConnection({
    host: dbConfig.HOST,
    user: dbConfig.USER,
    password: dbConfig.PASSWORD,
    database: dbConfig.DB
  });
  
  //      
  connection.connect(err => {
    if (err) throw error;
    console.log("    ");
  });

  module.exports = connection;
   //  

Create Model

In the folder model, we create a file called deal.model.js. If you have a question, what is a model in general, you should read an article like this and familiarize yourself with the MVC design pattern. I am going to create a constructor for a Deal object, and use connection for the following CRUD functions:

  • creation of a new business
  • finding case by id
  • getting all the cases
  • ability to update our case by id
  • Delete one case by id
  • complete deletion of all cases

Total, we have to do the following things:

  //   
  const Deal = function(deal) {
    this.text = deal.text;
  };
  //    ,        CRUD,      :
  Deal.create = (newDeal, result) => {
    sql.query("INSERT INTO TODO SET ?", newDeal, (err, res) => {
      //   SQL
      if (err) {
        console.log("error: ", err);
        result(err, null);
        //   ,     
        return;
      }
  
      console.log(" ", { id: res.insertId, ...newDeal });
      result(null, { id: res.insertId, ...newDeal });
    });
  };


I will place the rest of the code in the spoiler, because I don’t see any reason to bring it all, because in fact the code pattern is repeated there, only the sql commands and arguments change:

the rest of the code
Deal.findById = (dealId, result) => {
sql.query(`SELECT * FROM TODO WHERE id = ${dealId}`, (err, res) => {
if (err) {
console.log(«error: », err);
result(err, null);
return;
}

if (res.length) {
console.log(« : », res[0]);
result(null, res[0]);
return;
}

//
result({ kind: «not_found» }, null);
});
};

Deal.getAll = result => {
sql.query(«SELECT * FROM TODO», (err, res) => {
if (err) {
console.log(«error: », err);
result(null, err);
return;
}

console.log(«deals: », res);
result(null, res);
});
};

Deal.updateById = (id, deal, result) => {
sql.query(
«UPDATE TODO SET text =? WHERE id = ?»,
[deal.text, id],
(err, res) => {
if (err) {
console.log(«error: », err);
result(null, err);
return;
}

if (res.affectedRows == 0) {
result({ kind: «not_found» }, null);
return;
}

console.log(« », { id: id, ...deal });
result(null, { id: id, ...deal });
}
);
};

Deal.remove = (id, result) => {
sql.query(«DELETE FROM TODO WHERE id = ?», id, (err, res) => {
if (err) {
console.log(«error: », err);
result(null, err);
return;
}

if (res.affectedRows == 0) {
// id
result({ kind: «not_found» }, null);
return;
}
console.log(« », id);
result(null, res);
});
};

Deal.removeAll = result => {
sql.query(«DELETE FROM TODO», (err, res) => {
if (err) {
console.log(«error: », err);
result(null, err);
return;
}

console.log(`deleted ${res.affectedRows} deals`);
result(null, res);
});
};



That's all for now. The next part of this article is approaching, in which we finish writing the back and start testing it. And by tradition, a few useful links:


All Articles