Let’s build a Blog: Introduction to a single-paged application.

Greetings developers! The name’s Conway. I am the Lead Developer at a leading luxury agency in London. I have come to the conclusion that I would like to build something for myself; so I am going to build a fully functional blog and we are going to build the foundations together. I will not be taking the easy way out and using a pre-built CMS like WordPress, I will be building a single paged application from the ground up.

Table of Contents

The Stack

I will be using a primarily JavaScript stack. Sails.js will be used to build the server-side architecture. Sails.js is a MVC framework for Node.js built to 
rapidly develop JavaScript applications. With use of Sails’ Command-line interface, we can get our API up and running without having to write out all of the common code.

The front-end of the application will be built on Vue.js using Nuxt.js to handle the server side rendering. For demonstration purposes, I will be using Bootstrap 4 to visualise the front-ends foundation.

Before you start

Vital prerequisites are required for you to get started on the application. Essentially, you will need to have a basic understanding of JavaScript, HTML & CSS.

In order to install the node modules and run your application, you will need to have Node.js installed. Node is supported on both Windows and MacOS X, as well as many Linux distributions. You can download a supported pre-built installer from nodejs.org

You’ll need to have both Sails.js & Vue.js CLI installed, run
npm i sails @vue/cli @vue/cli-init -g in your terminal to do so. With an average internet speed, the installations should take less than 3 minutes to complete.

Finally, you will need to choose your IDE. I will be using WebStorm by JetBrains, which is amazing for modern JavaScript development. You can download ​a 30 day free trail or if you’re a student, get a free year licence.

I will be using Postman to test the our API endpoints, it is not essential, however I recommend installing it.

Let’s get started

Create a new project in your IDE and ensure that you have your terminal pointed to the directory.

First I will create an empty Sails app; to do this you just need to run sails new backend --no-frontend. This will create our API’s directory structure, to start the web server run sails lift within the backend directory. The application will now be served on localhost:1337.

I will use the Nuxt.js starter template to create the frontend directory, in your command line run vue init nuxt-community/starter-template frontend. Now, to get you the application running, you need to execute npm run dev. The application will now be running on localhost:3030.

The User Prototype

Sails.js ships with a sufficient way to set up API endpoints and actions that match your application architecture called Blueprints. The Blueprint API populates the restful API anytime you generate a Model and Controller without having to write any code! For example, when the User.js model and UserContorller.js controller files are created in your project, the Blueprints will allow you to visit /user/create?name=conway to create a user, and visit /user/to see a list of your applications users.

Blueprints are only enabled by default within development and are usually used when prototyping. However, in many cases, they can be used in production. For now we will be prototyping the User API and will not have to create our routes.

Now I will be using Sails.js’s Scaffolding tool to generate the User’s model and controller, to do this execute sails generate api user within your API’s directory. This will create the User.js and UserController.js within api folder. Now visit http://localhost:1337/user/create?name=conway; this will create the user and will output the user object as displayed below:

The Blueprints allow you to add any properties that you wish. But within my application, I want to declare my own properties. These will be: email Address, password and full name. To do this open up api/models/User.js and underneath primitives add the following:

emailAddress: {
type: 'string', // Sets the data type of the property to a string.
required: true, // Makes required when being created.
unique: true, // Declares that the property needs to be unique.
isEmail: true, // Declares that the property has to be an email.
maxLength: 200, // Sets the max length of the string.
example: 'conway@fullstackedkush.com' // Just an example.
},

password: {
type: 'string',
required: true,
protect: true, // Makes it a protected value.
},

fullName: {
type: 'string',
required: true,
maxLength: 120,
},

Every time you make a server-side change, you are required to restart the server.

If you were then to visit http://localhost:1337/user/create?name=conway the response header would be a bad request due to missing values for the required attributes.

Now that the user’s properties have been declared, I can now set the actions and routes. These can either be set within the User controller or declared as standalone actions.

For now, I will use the controller. For this, I will write a create function which will use the inputted data to create a user record within the database. To do this open up api/controllers/UserController.js and add the following:

// Create the user
create: function (req, res) {
// Set the requested parameters as variables.
let params = req.allParams();

// Validate requested parameters
if (!params.emailAddress)
return res.badRequest({
err: 'An email address is required.'
});

if (!params.fullName)
return res.badRequest({
err: 'You are required to enter your full name.'
});

if (!params.password)
return res.badRequest({
err: 'You are required to set a password.'
});

// Validate email address
let re = /\S+@\S+\.\S+/;
if (!re.test(params.emailAddress))
return res.badRequest({err: 'Email is invalid.'});
  // Check if user exists
User.find({or: [{emailAddress: params.emailAddress}]})
.exec( (err, users) => {
if (err)
return res.serverError({err: err.message});

if (users.length)
return res.badRequest({
err: 'User already exists'
});
      // If user doesn't exist create the user
User.create(params, (err, user) => {
if (err)
// return a server error if the user can not be created.
return res.serverError({err: err.message});
// Return the user if it is successfully created.
res.ok(user);
});
});
}

Next, I will need to declare which URL’s are distinguishable to the application. This gives you the ability to send a request to a URL and send back a response.

I will use Sails’ Router; this is where you can map the URL’s to actions. I will create a post request tohttp://localhost:1337/api/user/create; this will be mapped to the create function. To do this, open up config/routes.js and underneath API Endpoints, then add the following:

"post /api/user/create" : "UserController.create"

Now, I will test the request within Postman. On submitting the request, the user should be created and a response should include the user’s data.

What’s next?

I have covered everything we need to make a start on our application. We should now have a structured app directory and an understanding of how Sails handles Models and Controllers. In my next post I will be creating more in depth actions for the users to create, update, delete, and login/logout. As well as creating ​the post model and its actions, this will include Policies to authorise the CRUD requests. Part 2 can be found here!

The source for this series can be found on my GitHub, I will be updating the repo as I write each post. You can follow my instagram for updates and quick tutorials.