History: Node.js and Heroku

Revision made 7 years ago by Francisco Presencia. Go to the last revision.

Let's learn how to use javascript to program a server based on Node.js and upload the website to Heroku. First, a simple server; write this in a file called app.js:

let server = require('server');
let { get } = server.router;

server({},
  get('/', (req, res) => res.send('Hello world'))
);

Then in a file called .gitignore we will write this:

node_modules

Lastly, let's install server, our server framework.

npm install server --save

We will also install nodemon since it makes things much easier:

npm install nodemon -g

Now we can see that message on the server. Run nodemon and open localhost:3000:

nodemon

Routing

Now let's tell our server what files and how it should display. First let's just display index.html. In app.js, write this instead of our previous 'Hello world':

let server = require('server');
let { get, post } = server.router;

// Route
let home = get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html'));
}

server({}, home);

If we reopen localhost:3000 and refresh it we can see our index.html without any style or javascript.

The server will automatically know where our css and (front-end) javascript is, which is in a public named public by default. We could change this and the server port in the options:

server({ port: 8080, public: './static' }, ...);

Now let's create a route to get the file requested dynamically. We will get the url fragment as the variable name and then use it. Note: only the Route part is shown from now on:

let page = get('/:name', (req, res) => {
  console.log(req.params);
  res.send(req.params);
});

The previous one only shows us in the terminal what file we are reading and on the browser the file name. Let's actually display the file in the browser:

let page = get('/:name', (req, res) => {
  var file = __dirname + '/' + req.params.name + '.html';
  res.sendFile(file);
});

Forms

Let's try to create a form and handle it with Node.js. First we create the form in contact.html:

<!DOCTYPE html>
<html>
  <head>
    <title>Página Web</title>
    <meta charset="utf-8">
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/picnicss/6.1.1/picnic.min.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>

    <form action="/contacto" method="POST" class="contact">
      <h1>Contacto</h1>
      <input name="name" placeholder="Nombre">
      <input name="lastname" placeholder="Apellidos">
      <input name="age" placeholder="Edad">
      <input type="submit" value="Enviar">
    </form>

  </body>
</html>

And in style.css:

.contact {
  width: 500px;
  margin: 100px auto;
}

.contact input {
  margin-top: 0;
  margin-bottom: 10px;
}
Now we can read the data on the server. So far we won't be storing it, just display it on the terminal:
app.post('/contact', function(req, res){
  console.log(req.body);
  res.redirect('/');
});

If everything worked fine, this should display our data from the contact form and then redirect us home. We could change this for a /thankyou.html page or just handle it with javascript on the front-end and not redirect anywhere.

REST API

A REST API is a group of URLs and actions that can be done to them (GET, POST, PUT, DELETE). Let's say we have a user system. This would be a basic REST API for it:

GET /users            # Get all of the users data
GET /users/456546     # Get one specific user data
POST /users           # Create a new user
PUT /users/435465     # Edit an existing user
DELETE /users         # Remove all the users
DELETE /users/354643  # Remove a single user

This is useful on its own, but specially useful with mobile apps as well as webapps (React, Angular, etc). It separates our logic at some specific points and makes it easier to handle the complexity.

Let's make a small API that handles a Like button. In our app.js:

let server = require('server');
let { get, post, del } = server.router;

// An array with the ids of the things we liked
let likes = [];

// Retrieve all of our likes
let show = get('/likes', (req, res) => {
  res.json(likes);
});

// Create a new like
let add = post('/likes/:id', (req, res) => {
  let id = req.params.id;
  likes.push(id);
  res.json({ added: true });
});

// Remove a like
let remove = del('/likes/:id', (req, res) => {
  let id = req.params.id;
  let index = likes.indexOf(id);
  likes.splice(index, 1)
  res.json({ deleted: true });
});

server({}, show, add, remove);

Now we can have a list of items that can be liked:

<main>
  <ul>
    <li>First <button data-id="1">Like</button></li>
    <li>Second <button data-id="2">Like</button></li>
    <li>Third <button data-id="3">Like</button></li>
    <li>Fourth <button data-id="4">Like</button></li>
  </ul>
</main>

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
  // Load all the likes and add the class 'active' to the ones we liked
  $(document).ready(function(){
    $.get('/likes/', function(likes){
      likes.forEach(function(id){
        $('button[data-id="' + id + '"]').addClass('active');
      });
    });
  });

  // Handle the button clicks
  $('button').on('click', function(e){
    var id = $(e.target).attr('<main>
  <ul>
    <li>First <button data-id="1">Like</button></li>
    <li>Second <button data-id="2">Like</button></li>
    <li>Third <button data-id="3">Like</button></li>
    <li>Fourth <button data-id="4">Like</button></li>
  </ul>
</main>

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
  // Load all the likes and add the class 'active' to the ones we liked
  $(document).ready(function(){
    $.get('/likes/', function(likes){
      likes.forEach(function(id){
        $('button[data-id="' + id + '"]').addClass('active');
      });
    });
  });

  // Handle the button clicks
  $('button').on('click', function(e){
    var id = $(e.target).attr('

Exercise: make a dislike button that calls the route /dislike through POST and DELETE and shows on the browser console what the server is doing.