Monthly Archives: December 2016

Build a CRUD Web App With Python and Flask – Part One

By mbithenzomo

oEGZ93DzRw2JMGZStUKE_flask-crud-part-one.jpg

In this three-part tutorial, we’ll build a CRUD (Create, Read, Update, Delete) employee management web app using Flask, a microframework for Python. I’ve named the app Project Dream Team, and it will have the following features:

  1. Users will be able to register and login as employees
  2. The administrator will be able to create, update, and delete departments and roles
  3. The administrator will be able to assign employees to a department and assign them roles
  4. The administrator will be able to view all employees and their details

Part One will cover:

  1. Database setup
  2. Models
  3. Migration
  4. Homepage
  5. Authentication

Ready? Here we go!

Prerequisites

This tutorial builds on my introductory tutorial, Getting Started With Flask, picking up where it left off. It assumes you have, to begin with, the following dependencies installed:

  1. Python 2.7
  2. Flask
  3. virtualenv (and, optionally, virtualenvwrapper)

You should have a virtual environment set up and activated. You should also have the following file and directory structure:

├── dream-team
       ├── app
       │   ├── __init__.py
       │   ├── templates
       │   ├── models.py
       │   └── views.py
       ├── config.py
       ├── requirements.txt
       └── run.py

This project structure groups the similar components of the application together. The dream-team directory houses all the project files. The app directory is the application package, and houses different but interlinked modules of the application. All templates are stored in the templates directory, all models are in the models.py file, and all routes are in the views.py file. The run.py file is the application’s entry point, the config.py file contains the application configurations, and the requirements.txt file contains the software dependencies for the application.

If you don’t have these set up, please visit the introductory tutorial and catch up!

Database Setup

Flask has support for several relational database management systems, including SQLite, MySQL, and PostgreSQL. For this tutorial, we will be using MySQL. It’s popular and therefore has a lot of support, in addition to being scalable, secure, and rich in features.

We will install the following (remember to activate your virtual environment):

  1. Flask-SQLAlchemy: This will allow us to use SQLAlchemy, a useful tool for SQL use with Python. SQLAlchemy is an Object Relational Mapper (ORM), which means that it connects the objects of an application to tables in a relational database management system. These objects can be stored in the database and accessed without the need to write raw SQL. This is convenient because it simplifies queries that may have been complex if written in raw SQL. Additionally, it reduces the risk of SQL injection attacks since we are not dealing with the input of raw SQL.

  2. MySQL-Python: This is a Python interface to MySQL. It will help us connect the MySQL database to the app.
$ pip install flask-sqlalchemy mysql-python

We’ll then create the MySQL database. Ensure you have MySQL installed and running, and then log in as the root user:

$ mysql -u root

mysql> CREATE USER 'dt_admin'@'localhost' IDENTIFIED BY 'dt2016';
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE DATABASE dreamteam_db;
Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON dreamteam_db . * TO 'dt_admin'@'localhost';
Query OK, 0 rows affected (0.00 sec)

We have now created a new user dt_admin with the password dt2016, created a new database dreamteam_db, and granted the new user all database privileges.

Next, let’s edit the config.py. Remove any exisiting code and add the following:

# config.py

class Config(object):
    """
    Common configurations
    """

    # Put any configurations here that are common across all environments

class DevelopmentConfig(Config):
    """
    Development configurations
    """

    DEBUG = True
    SQLALCHEMY_ECHO = True

class ProductionConfig(Config):
    """
    Production configurations
    """

    DEBUG = False

app_config = {
    'development': DevelopmentConfig,
    'production': ProductionConfig
}

It is good practice to specify configurations for different environments. In the file above, we have specifed configurations for development, which we will use while building the app and running it locally, as well as production, which we will use when the app is deployed.

Some useful configuration variables are:

  1. TESTING: setting this to True activates the testing mode of Flask extensions. This allows us to use testing properties that could for instance have an increased runtime cost, such as unittest helpers. It should be set to True in the configurations for testing. It defaults to False.
  2. DEBUG: setting this to True activates the debug mode on the app. This allows us to use the Flask debugger in case of an unhandled exception, and also automatically reloads the application when it is updated. It should however always be set to False in production. It defaults to False.
  3. SQLALCHEMY_ECHO: setting this to True helps us with debugging by allowing SQLAlchemy to log errors.

You can find more Flask configuration variables here and SQLAlchemy configuration variables here.

Next, create an instance directory in the dream-team directory, and then create a config.py file inside it. We will put configuration variables here that will not be pushed to version control due to their sensitive nature. In this case, we put the secret key as well as the database URI which contains the database user password.

# instance/config.py

SECRET_KEY = 'p9Bv<3Eid9%$i01'
SQLALCHEMY_DATABASE_URI = 'mysql://dt_admin:dt2016@localhost/dreamteam_db'

Now, let’s edit the app/__init__.py file. Remove any existing code and add the following:

# app/__init__.py

# third-party imports
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# local imports
from config import app_config

# db variable initialization
db = SQLAlchemy()

def create_app(config_name):
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_object(app_config[config_name])
    app.config.from_pyfile('config.py')
    db.init_app(app)

    return app

We’ve created a function, create_app that, given a configuration name, loads the correct configuration from the config.py file, as well as the configurations from the instance/config.py file. We have also created a db object which we will use to interact with the database.

Next, let’s edit the run.py file:

# run.py

import os

from app import create_app

config_name = os.getenv('FLASK_CONFIG')
app = create_app(config_name)

if __name__ == '__main__':
    app.run()

We create the app by running the create_app function and passing in the configuration name. We get this from the OS environment variable FLASK_CONFIG. Because we are in development, we should set the environment variable to development.

Let’s run the app to ensure everything is working as expected. First, delete the app/views.py file as well as the app/templates directory as we will not be needing them going forward. Next, add a temporary route to the app/__init__.py file as follows:

# app/__init__.py

# existing code remains

def create_app(config_name):
    # existing code remains

    # temporary route
    @app.route('/')
    def hello_world():
        return 'Hello, World!'

    return app

Make sure you set the FLASK_CONFIG and FLASK_APP environment variables before running the app:

$ export FLASK_CONFIG=development
$ export FLASK_APP=run.py
$ flask run
 * Serving Flask app "run"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

We can see the “Hello, World” string we set in the route. The app is working well so far.

Models

Now to work on the models. Remember that a model is a representation of a database table in code. We’ll need three models: Employee, Department, and Role.

But first, let’s install Flask-Login, which will help us with user management and handle logging in, logging out, and user sessions. The Employee model will inherit from Flask-Login’s UserMixin class which will make it easier for us to make use of its properties and methods.

$ pip install flask-login

To use Flask-Login, we need to create a LoginManager object and initialize it in the app/__init__.py file. First, remove the route we added earlier, and then add the following:

# app/__init__.py

# after existing third-party imports
from flask_login import LoginManager

# after the db variable initialization
login_manager = LoginManager()

def create_app(config_name):
    # existing code remains

    login_manager.init_app(app)
    login_manager.login_message = "You must be logged in to access this page."
    login_manager.login_view = "auth.login"

    return app

In addition to initializing the LoginManager object, we’ve also added a login_view and login_message to it. This way, if a user tries to access a page that they are not authorized to, it will redirect to the specified view and display the specified message. We haven’t created the auth.login view yet, but we will when we get to authentication.

Now add the following code to the app/models.py file:

# app/models.py

from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash

from app import db, login_manager

class Employee(UserMixin, db.Model):
    """
    Create an Employee table
    """

    # Ensures table will be named in plural and not in singular
    # as is the name of the model
    __tablename__ = 'employees'

    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(60), index=True, unique=True)
    username = db.Column(db.String(60), index=True, unique=True)
    first_name = db.Column(db.String(60), index=True)
    last_name = db.Column(db.String(60), index=True)
    password_hash = db.Column(db.String(128))
    department_id = db.Column(db.Integer, db.ForeignKey('departments.id'))
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    is_admin = db.Column(db.Boolean, default=False)

    @property
    def password(self):
        """
        Prevent pasword from being accessed
        """
        raise AttributeError('password is not a readable attribute.')

    @password.setter
    def password(self, password):
        """
        Set password to a hashed password
        """
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        """
        Check if hashed password matches actual password
        """
        return check_password_hash(self.password_hash, password)

    def __repr__(self):
        return '<Employee: {}>'.format(self.username)

# Set up user_loader
@login_manager.user_loader
def load_user(user_id):
    return Employee.query.get(int(user_id))

class Department(db.Model):
    """
    Create a Department table
    """

    __tablename__ = 'departments'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(60), unique=True)
    description = db.Column(db.String(200))
    employees = db.relationship('Employee', backref='department',
                                lazy='dynamic')

    def __repr__(self):
        return '<Department: {}>'.format(self.name)

class Role(db.Model):
    """
    Create a Role table
    """

    __tablename__ = 'roles'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(60), unique=True)
    description = db.Column(db.String(200))
    employees = db.relationship('Employee', backref='role',
                                lazy='dynamic')

    def __repr__(self):
        return '<Role: {}>'.format(self.name)

In the Employee model, we make use of some of Werkzeug’s handy security helper methods, generate_password_hash, which allows us to hash passwords, and check_password_hash, which allows us ensure the hashed password matches the password. To enhance security, we have a password method which ensures that the password can never be accessed; instead an error will be raised. We also have two foreign key fields, department_id and role_id, which refer to the ID’s of the department and role assigned to the employee.

Note that we have an is_admin field which is set to False by default. We will override this when creating the admin user. Just after the Employee model, we have a user_loader callback, which Flask-Login uses to reload the user object from the user ID stored in the session.

The Department and Role models are quite similar. Both have name and description fields. Additionally, both have a one-to-many relationship with the Employee model (one department or role can have many employees). We define this in both models using the employees field. backref allows us to create a new property on the Employee model such that we can use employee.department or employee.role to get the department or role assigned to that employee. lazy defines how the data will be loaded from the database; in this case it will be loaded dynamically, which is ideal for managing large collections.

Migration

Migrations allow us to manage changes we make to the models, and propagate these changes in the database. For example, if later on we make a change to a field in one of the models, all we will need to do is create and apply a migration, and the database will reflect the change.

We’ll begin by installing Flask-Migrate, which will handle the database migrations using Alembic, a lightweight database migration tool. Alembic emits ALTER statements to a database thus implememting changes made to the models. It also auto-generates minimalistic migration scripts, which may be complex to write.

$ pip install flask-migrate

We’ll need to edit the app/__init__.py file:

# app/__init__.py

# after existing third-party imports
from flask_migrate import Migrate

# existing code remains

def create_app(config_name):
    # existing code remains

    migrate = Migrate(app, db)

    from app import models

    return app

We have created a migrate object which will allow us to run migrations using Flask-Migrate. We have also imported the models from the app package. Next, we’ll run the following command to create a migration repository:

$ flask db init

This creates a migrations directory in the dream-team directory:

└── migrations
    ├── README
    ├── alembic.ini
    ├── env.py
    ├── script.py.mako
    └── versions

Next, we will create the first migration:

$ flask db migrate

Finally, we’ll apply the migration:

$ flask db upgrade

We’ve sucessfully created tables based on the models we wrote! Let’s check the MySQL database to confirm this:

$ mysql -u root

mysql> use dreamteam_db;

mysql> show tables;
+------------------------+
| Tables_in_dreamteam_db |
+------------------------+
| alembic_version        |
| departments            |
| employees              |
| roles                  |
+------------------------+
4 rows in set (0.00 sec)

Blueprints

Blueprints are great for organising a flask app into components, each with its own views and forms. I find that blueprints make for a cleaner and more organised project structure because each blueprint is a distinct component that addresses a specific functionality of the app. Each blueprint can even have its own cutsom URL prefix or subdomain. Blueprints are particularly convenient for large applications.

We’re going to have three blueprints in this app:

  1. Home – this will have the homepage and dashboard views
  2. Admin – this will have all administrator (department and role) forms and views
  3. Auth – this will have all authentication (registration and login) forms and views

Create the relevant files and directories so that your directory structure resembles this:

└── dream-team
    ├── app
    │   ├── __init__.py
    │   ├── admin
    │   │   ├── __init__.py
    │   │   ├── forms.py
    │   │   └── views.py
    │   ├── auth
    │   │   ├── __init__.py
    │   │   ├── forms.py
    │   │   └── views.py
    │   ├── home
    │   │   ├── __init__.py
    │   │   └── views.py
    │   ├── models.py
    │   ├── static
    │   └── templates
    ├── config.py
    ├── instance
    │   └── config.py
    ├── migrations
    │   ├── README
    │   ├── alembic.ini
    │   ├── env.py
    │   ├── script.py.mako
    │   └── versions
    │       └── a1a1d8b30202_.py
    ├── requirements.txt
    └── run.py

I chose not to have static and templates directories for each blueprint, because all the application templates will inherit from the same base template and use the same CSS file. Instead, the templates directory will have sub-directories for each blueprint so that blueprint templates can be grouped together.

In each blueprint’s __init__.py file, we need to create a Blueprint object and initialize it with a name. We also need to import the views.

# app/admin/__init__.py

from flask import Blueprint

admin = Blueprint('admin', __name__)

from . import views
# app/auth/__init__.py

from flask import Blueprint

auth = Blueprint('auth', __name__)

from . import views
# app/home/__init__.py

from flask import Blueprint

home = Blueprint('home', __name__)

from . import views

Then, we can register the blueprints on the app in the app/__init__.py file, like so:

# app/__init__.py

# existing code remains

def create_app(config_name):
    # existing code remains

    from app import models

    from .admin import admin as admin_blueprint
    app.register_blueprint(admin_blueprint, url_prefix='/admin')

    from .auth import auth as auth_blueprint
    app.register_blueprint(auth_blueprint)

    from .home import home as home_blueprint
    app.register_blueprint(home_blueprint)

    return app

We have imported each blueprint object and registered it. For the admin blueprint, we have added a url prefix, /admin. This means that all the views for this blueprint will be accessed in the browser with the url prefix admin.

Home Blueprint

Time to work on fleshing out the blueprints! We’ll start with the home blueprint, which will have the homepage as well as the dashboard.

# app/home/views.py

from flask import render_template
from flask_login import login_required

from . import home

@home.route('/')
def homepage():
    """
    Render the homepage template on the / route
    """
    return render_template('home/index.html', title="Welcome")

@home.route('/dashboard')
@login_required
def dashboard():
    """
    Render the dashboard template on the /dashboard route
    """
    return render_template('home/dashboard.html', title="Dashboard")

Each view function has a decorator, home.route, which has a URL route as a parameter (remember that home is the name of the blueprint as specified in the app/home/__init__.py file). Each view handles requests to the specified URL.

The homepage view renders the home template, while the dashboard view renders the dashboard template. Note that the dashboard view has a login_required decorator, meaning that users must be logged in to access it.

Now to work on the base template, which all other templates will inherit from. Create a base.html file in the app/templates directory and add the following code:

<!-- app/templates/base.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <title>{{ title }} | Project Dream Team</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
    <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.ico') }}">
</head>
<body>
    <nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation">
        <div class="container topnav">
          <div class="navbar-header">
              <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                  <span class="sr-only">Toggle navigation</span>
                  <span class="icon-bar"></span>
                  <span class="icon-bar"></span>
                  <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand topnav" href="{{ url_for('home.homepage') }}">Project Dream Team</a>
          </div>
          <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
              <ul class="nav navbar-nav navbar-right">
                  <li><a href="{{ url_for('home.homepage') }}">Home</a></li>
                  <li><a href="#">Register</a></li>
                  <li><a href="#">Login</a></li>
              </ul>
          </div>
        </div>
    </nav>
    <div class="wrapper">
      {% block body %}
      {% endblock %}
      <div class="push"></div>
    </div>
    <footer>
        <div class="container">
            <div class="row">
                <div class="col-lg-12">
                    <ul class="list-inline">
                        <li><a href="{{ url_for('home.homepage') }}">Home</a></li>
                        <li class="footer-menu-divider">⋅</li>
                        <li><a href="#">Register</a></li>
                        <li class="footer-menu-divider">⋅</li>
                        <li><a href="#">Login</a></li>
                    </ul>
                    <p class="copyright text-muted small">Copyright © 2016. All Rights Reserved</p>
                </div>
            </div>
        </div>
    </footer>
</body>
</html>

Note that we use # for the Register and Login links. We will update this when we are working on the auth blueprint.

Next, create a home directory inside the app/templates directory. The homepage template, index.html, will go inside it:

<!-- app/templates/home/index.html -->

{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block body %}
<div class="intro-header">
    <div class="container">
        <div class="row">
            <div class="col-lg-12">
                <div class="intro-message">
                    <h1>Project Dream Team</h1>
                    <h3>The best company in the world!</h3>
                    <hr class="intro-divider">
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

Inside the static directory, add css and img directories. Add the following CSS file, style.css, to your static/css directory (note that you will need a background image, intro-bg.jpg, as well as a favicon in your static/img directory):

/* app/static/css/style.css */

body, html {
    width: 100%;
    height: 100%;
}

body, h1, h2, h3 {
    font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-weight: 700;
}

a, .navbar-default .navbar-brand, .navbar-default .navbar-nav>li>a {
  color: #aec251;
}

a:hover, .navbar-default .navbar-brand:hover, .navbar-default .navbar-nav>li>a:hover {
  color: #687430;
}

footer {
    padding: 50px 0;
    background-color: #f8f8f8;
}

p.copyright {
    margin: 15px 0 0;
}

.alert-info {
    width: 50%;
    margin: auto;
    color: #687430;
    background-color: #e6ecca;
    border-color: #aec251;
}

.btn-default {
    border-color: #aec251;
    color: #aec251;
}

.btn-default:hover {
    background-color: #aec251;
}

.center {
    margin: auto;
    width: 50%;
    padding: 10px;
}

.content-section {
    padding: 50px 0;
    border-top: 1px solid #e7e7e7;
}

.footer, .push {
  clear: both;
  height: 4em;
}

.intro-divider {
    width: 400px;
    border-top: 1px solid #f8f8f8;
    border-bottom: 1px solid rgba(0,0,0,0.2);
}

.intro-header {
    padding-top: 50px;
    padding-bottom: 50px;
    text-align: center;
    color: #f8f8f8;
    background: url(../img/intro-bg.jpg) no-repeat center center;
    background-size: cover;
    height: 100%;
}

.intro-message {
    position: relative;
    padding-top: 20%;
    padding-bottom: 20%;
}

.intro-message > h1 {
    margin: 0;
    text-shadow: 2px 2px 3px rgba(0,0,0,0.6);
    font-size: 5em;
}

.intro-message > h3 {
    text-shadow: 2px 2px 3px rgba(0,0,0,0.6);
}

.lead {
    font-size: 18px;
    font-weight: 400;
}

.topnav {
    font-size: 14px;
}

.wrapper {
  min-height: 100%;
  height: auto !important;
  height: 100%;
  margin: 0 auto -4em;
}

Run the app; you should be able to see the homepage now.

Auth Blueprint

For the auth blueprint, we’ll begin by creating the registration and login forms. We’ll use Flask-WTF, which will allow us to create forms that are secure (thanks to CSRF protection and reCAPTCHA support).

pip install Flask-WTF

Now to write the code for the forms:

# app/auth/forms.py

from flask_wtf import FlaskForm
from wtforms import PasswordField, StringField, SubmitField, ValidationError
from wtforms.validators import DataRequired, Email, EqualTo

from ..models import Employee

class RegistrationForm(FlaskForm):
    """
    Form for users to create new account
    """
    email = StringField('Email', validators=[DataRequired(), Email()])
    username = StringField('Username', validators=[DataRequired()])
    first_name = StringField('First Name', validators=[DataRequired()])
    last_name = StringField('Last Name', validators=[DataRequired()])
    password = PasswordField('Password', validators=[
                                        DataRequired(),
                                        EqualTo('confirm_password')
                                        ])
    confirm_password = PasswordField('Confirm Password')
    submit = SubmitField('Register')

    def validate_email(self, field):
        if Employee.query.filter_by(email=field.data).first():
            raise ValidationError('Email is already in use.')

    def validate_username(self, field):
        if Employee.query.filter_by(username=field.data).first():
            raise ValidationError('Username is already in use.')

class LoginForm(FlaskForm):
    """
    Form for users to login
    """
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    submit = SubmitField('Login')

Flask-WTF has a number of validators that make writing forms much easier. All the fields in the models have the DataRequired validator, which means that users will be required to fill all of them in order to register or login.

For the registration form, we require users to fill in their email address, username, first name, last name, and their password twice. We use the Email validator to ensure valid email formats are used (e.g some-name@some-domain.com.) We use the EqualTo validator to confirm that the password and confirm_password fields in the RegistrationForm match. We also create methods (validate_email and validate_username) to ensure that the email and username entered have not been used before.

The submit field in both forms will be represented as a button that users will be able to click to register and login respectively.

With the forms in place, we can write the views:

# app/auth/views.py

from flask import flash, redirect, render_template, url_for
from flask_login import login_required, login_user, logout_user

from . import auth
from forms import LoginForm, RegistrationForm
from .. import db
from ..models import Employee

@auth.route('/register', methods=['GET', 'POST'])
def register():
    """
    Handle requests to the /register route
    Add an employee to the database through the registration form
    """
    form = RegistrationForm()
    if form.validate_on_submit():
        employee = Employee(email=form.email.data,
                            username=form.username.data,
                            first_name=form.first_name.data,
                            last_name=form.last_name.data,
                            password=form.password.data)

        # add employee to the database
        db.session.add(employee)
        db.session.commit()
        flash('You have successfully registered! You may now login.')

        # redirect to the login page
        return redirect(url_for('auth.login'))

    # load registration template
    return render_template('auth/register.html', form=form, title='Register')

@auth.route('/login', methods=['GET', 'POST'])
def login():
    """
    Handle requests to the /login route
    Log an employee in through the login form
    """
    form = LoginForm()
    if form.validate_on_submit():

        # check whether employee exists in the database and whether
        # the password entered matches the password in the database
        employee = Employee.query.filter_by(email=form.email.data).first()
        if employee is not None and employee.verify_password(
                form.password.data):
            # log employee in
            login_user(employee)

            # redirect to the dashboard page after login
            return redirect(url_for('home.dashboard'))

        # when login details are incorrect
        else:
            flash('Invalid email or password.')

    # load login template
    return render_template('auth/login.html', form=form, title='Login')

@auth.route('/logout')
@login_required
def logout():
    """
    Handle requests to the /logout route
    Log an employee out through the logout link
    """
    logout_user()
    flash('You have successfully been logged out.')

    # redirect to the login page
    return redirect(url_for('auth.login'))

Just like in the home blueprint, each view here handles requests to the specified URL. The register view creates an instance of the Employee model class using the registration form data to populate the fields, and then adds it to the database. This esentially registers a new employee.

The login view queries the database to check whether an employee exists with an email address that matches the email provided in the login form data. It then uses the verify_password method to check that the password in the database for the employee matches the password provided in the login form data. If both of these are true, it proceeds to log the user in using the login_user method provided by Flask-Login.

The logout view has the login_required decorator, which means that a user must be logged in to access it. It calles the logout_user method provided by Flask-Login to log the user out.

Note the use of flash method, which allows us to use Flask’s message flashing feature. This allows us to communicate feedback to the user, such as informing them of successful registration or unsuccessful login.

Finally, let’s work on the templates. First, we’ll install Flask-Bootstrap so we can use its wtf and utils libraries. The wtf library will allow us to quickly generate forms in the templates based on the forms in the forms.py file. The utils library will allow us to display the flash messages we set earlier to give feedback to the user.

pip install flask-bootstrap

We need to edit the app/__init__.py file to use Flask-Bootstrap:

# app/__init__.py

# after existing third-party imports
from flask_bootstrap import Bootstrap

# existing code remains

def create_app(config_name):
    # existing code remains

    Bootstrap(app)

    from app import models

    # blueprint registration remains here

    return app

We’ve made quite a number of edits to the app/__init__.py file. This is the final version of the file and how it should look at this point (note that I have re-arranged the imports and variables in alphabetical order):

# app/__init__.py

# third-party imports
from flask import Flask
from flask_bootstrap import Bootstrap
from flask_login import LoginManager
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy

# local imports
from config import app_config

db = SQLAlchemy()
login_manager = LoginManager()

def create_app(config_name):
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_object(app_config[config_name])
    app.config.from_pyfile('config.py')

    Bootstrap(app)
    db.init_app(app)
    login_manager.init_app(app)
    login_manager.login_message = "You must be logged in to access this page."
    login_manager.login_view = "auth.login"
    migrate = Migrate(app, db)

    from app import models

    from .admin import admin as admin_blueprint
    app.register_blueprint(admin_blueprint, url_prefix='/admin')

    from .auth import auth as auth_blueprint
    app.register_blueprint(auth_blueprint)

    from .home import home as home_blueprint
    app.register_blueprint(home_blueprint)

    return app

We need two templates for the auth blueprint: register.html and login.html, which we’ll create in an auth directory inside the templates directory.

<!-- app/templates/auth/register.html -->

{% import "bootstrap/wtf.html" as wtf %}
{% extends "base.html" %}
{% block title %}Register{% endblock %}
{% block body %}
<div class="content-section">
  <div class="center">
    <h1>Register for an account</h1>
    <br/>
    {{ wtf.quick_form(form) }}
  </div>
</div>
{% endblock %}
<!-- app/templates/auth/login.html -->

{% import "bootstrap/utils.html" as utils %}
{% import "bootstrap/wtf.html" as wtf %}
{% extends "base.html" %}
{% block title %}Login{% endblock %}
{% block body %}
<div class="content-section">
  <br/>
  {{ utils.flashed_messages() }}
  <br/>
  <div class="center">
    <h1>Login to your account</h1>
    <br/>
    {{ wtf.quick_form(form) }}
  </div>
</div>
{% endblock %}

The forms are loaded from the app/auth/views.py file, where we specified which template files to display for each view. Remember the Register and Login links in the base template? Let’s update them now so we can access the pages from the menus:

<!-- app/templates/base.html -->

<!-- Modify nav bar menu -->
<ul class="nav navbar-nav navbar-right">
    <li><a href="{{ url_for('home.homepage') }}">Home</a></li>
    <li><a href="{{ url_for('auth.register') }}">Register</a></li>
    <li><a href="{{ url_for('auth.login') }}">Login</a></li>
</ul>

<!-- Modify footer menu -->
<ul class="list-inline">
    <li><a href="{{ url_for('home.homepage') }}">Home</a></li>
    <li class="footer-menu-divider">⋅</li>
    <li><a href="{{ url_for('auth.register') }}">Register</a></li>
    <li class="footer-menu-divider">⋅</li>
    <li><a href="{{ url_for('auth.login') }}">Login</a></li>
</ul>

Run the app again and click on the Register and Login menu links. You should see the templates loaded with the appropriate form.

Try to fill out the registration form; you should be able to register a new employee. After registration, you should be redirected to the login page, where you will see the flash message we configured in the app/auth/views.py file, inviting you to login.

Logging in should be successful; however you should get a Template Not Found error after logging in, because the dashboard.html template has not been created yet. Let’s do that now:

<!-- app/templates/home/dashboard.html -->

{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block body %}
<div class="intro-header">
    <div class="container">
        <div class="row">
            <div class="col-lg-12">
                <div class="intro-message">
                    <h1>The Dashboard</h1>
                    <h3>We made it here!</h3>
                    <hr class="intro-divider">
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

Refresh the page. You’ll notice that the navigation menu still has the register and login links, even though we are already logged in. We’ll need to modify it to show a logout link when a user is already authenticated. We will also include a Hi, username! message in the nav bar:

<!-- app/templates/base.html -->

<!-- In the head tag, include link to Font Awesome CSS so we can use icons -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">

<!-- Modify nav bar menu -->
<ul class="nav navbar-nav navbar-right">
    {% if current_user.is_authenticated %}
      <li><a href="{{ url_for('home.dashboard') }}">Dashboard</a></li>
      <li><a href="{{ url_for('auth.logout') }}">Logout</a></li>
      <li><a><i class="fa fa-user"></i>  Hi, {{ current_user.username }}!</a></li>
    {% else %}
      <li><a href="{{ url_for('home.homepage') }}">Home</a></li>
      <li><a href="{{ url_for('auth.register') }}">Register</a></li>
      <li><a href="{{ url_for('auth.login') }}">Login</a></li>
    {% endif %}
</ul>

<!-- Modify footer menu -->
<ul class="list-inline">
    <li><a href="{{ url_for('home.homepage') }}">Home</a></li>
    <li class="footer-menu-divider">⋅</li>
    {% if current_user.is_authenticated %}
      <li><a href="{{ url_for('auth.logout') }}">Logout</a></li>
    {% else %}
      <li><a href="{{ url_for('auth.register') }}">Register</a></li>
      <li class="footer-menu-divider">⋅</li>
      <li><a href="{{ url_for('auth.login') }}">Login</a></li>
    {% endif %}
</ul>

Note how we use if-else statements in the templates. Also, take note of the current_user proxy provided by Flask-Login, which allows us to check whether the user is authenticated and to get the user’s username.

Logging out will take you back to the login page:

Attempting to access the dashboard page without logging in will redirect you to the login page and display the message we set in the app/__init__.py file:

Notice that the URL is configured such that once you log in, you will be redirected to the page you initially attempted to access, which in this case is the dashboard.

Conclusion

That’s it for Part One! We’ve covered quite a lot: setting up a MySQL database, creating models, migrating the database, and handling registration, login, and logout. Good job for making it this far!

Watch this space for Part Two, which will cover the CRUD functionality of the app, allowing admin users to add, list, edit, and delete departments and roles, as well as assign them to employees.

Source:: scotch.io

Build a Realtime Chat Server With Go and WebSockets

By mark3labs

M39cybXZRMOz2dTiGFIk_build-a-realtime-chat-server-with-go.png.jpg

Modern web applications are becoming more and complex. Users are often greeted with an experience that is both reactive and engaging. Pages update in real time without the user having to initiate calls to the server or refreshing their browser. In the early days, developers relied on AJAX requests to create applications that were pretty close to realtime. Now they’re able to use the power of WebSockets to create fully realtime applications.

In this tutorial we’ll create a realtime chat application using the Go programming language and WebSockets. The frontend will be written using HTML5 and VueJS. A basic understanding of the Go language, JavaScript and HTML5 are assumed. It’s also assumed that you have a little bit of experience working with VueJS.

To get started with Go, you can check out the excellent interactive tutorial on the official Go website. https://tour.golang.org/welcome/1

And for Vue you can check out the excellent free video series by Jeffrey Way at Laracasts. https://laracasts.com/series/learn-vue-2-step-by-step

What Is a WebSocket?

Normal web applications are served up using at least one or more requests to an HTTP server. A piece of client software, normally a web browser sends a request to the server and the server sends back a response. The response is usually HTML which the browser then renders as a web page. Stylesheets, JavaScript code and images can also be sent back in a response to complete the entire web page. Each request and response is part of its own separate connection and a large website like Facebook can actually yield hundreds of these connections just to render a single page.

AJAX works the exact same way. Using JavaScript, developers can make requests to the HTTP server for little pieces of information and then update a single part of the webpage based on the response. This can all be done without having to refresh the browser. This still has some limitations though.

Each HTTP request/response connection is closed after the response and to get any new information another connection must be made. The server has no idea the client is looking for new information without a new request to tell it so. One technique to make AJAX applications seem realtime is to run AJAX requests in a timed loop. After a set interval, the application can rerun a request to the server to see if there has been any update which needs to be reflected in the browser. This works fine for small applications but is not very efficient. This is where WebSockets come in handy.

WebSockets are part of a prosposed standard created by the Internet Engineering Task Force (IETF). The full specification of how WebSockets should be implemented are detailed in RFC6455. Here is how the document defines a WebSocket.

The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code.

In other words, a WebSocket is a connection that is always open and allows a client and server to send messages back and forth unprompted. The server can push new information to the client whenever it deems it necessary and the client can do the same to the server.

WebSockets in JavaScript

Most modern browsers have support for WebSockets in their JavaScript implementation. To initiate a WebSocket connection from the browser you can use the simple WebSocket JavaScript object like this.

    var ws = new Websocket("ws://example.com/ws");

The only argument you need is a URL to where the WebSocket connection is going to be accepted by the server. The request is actually an HTTP request initially but we use “ws://” or “wss://” for a secure connection. This lets the server know that we are trying to create a new WebSocket connection. The server will then “upgrade” the connection to a persistent two-way connection between the client and server.

Once a new WebSocket object is created and the connected is successfully created we can use the “send()” method to send text to the server and define a handler function on our WebSocket’s “onmessage” property to do something with messages sent from the server. This will be explained later in our chat application code.

WebSockets In Go

WebSockets are not included as part of the Go standard library but thankfully there are a few nice third-party packages that make working with WebSockets a breeze. In this example we will use a package called “gorilla/websocket” which is part of the popular Gorilla Toolkit collection of packages for creating web applications in Go. To install it, simply run the following.

$ go get github.com/gorilla/websocket

Building the Server

The first piece of this application is going to be the server. It will be a simple HTTP server that handles requests. It will serve up our HTML5 and JavaScript code as well as complete the setup of WebSocket connections from clients. Going a step further, the server will also keep track of each WebSocket connection and relay chat messages sent from one client to all other clients connected by WebSocket. Start by creating a new empty directory then inside that directory, create a “src” and “public” directory. Inside the “src” directory create a file called “main.go”.

The first part of the application is some setup. We start our application like all Go applications and define our package namespace, in this case “main”. Next we import some useful packages. “log” and “net/http” are both part of the standard library and will be used to log (duh) and create a simple HTTP server. The final package, “github.com/gorilla/websocket”, will help us easily create and work with our WebSocket connections.

package main

import (
        "log"
        "net/http"

        "github.com/gorilla/websocket"
)

The next two lines are some global variables that will be used by the rest of the app. Global variables are usually a bad practice but we will use them this time for simplicity. The first variable is a map where the key is actually a pointer to a WebSocket. The value is just a boolean. The value isn’t actually needed but we are using a map because it is easier than an array to append and delete items.

The second variable is a channel that will act as a queue for messages sent by clients. Later in the code, we will define a goroutine to read new messages from the channel and then send them to the other clients connected to the server.

var clients = make(map[*websocket.Conn]bool) // connected clients
var broadcast = make(chan Message)           // broadcast channel

Next we create an instance of an upgrader. This is just an object with methods for taking a normal HTTP connection and upgrading it to a WebSocket as we’ll see later in the code.

// Configure the upgrader
var upgrader = websocket.Upgrader{}

Finally we’ll define an object to hold our messages. It’s a simple struct with some string attributes for an email address, a username and the actual message. We’ll use the email to display a unique avatar provided by the popular Gravatar service.

The text surrounded by backticks is just metadata which helps Go serialize and unserialize the Message object to and from JSON.

// Define our message object
type Message struct {
        Email    string `json:"email"`
        Username string `json:"username"`
        Message  string `json:"message"`
}

The main entry point of any Go application is always the “main()” function. The code is pretty simple. We first create a static fileserver and tie that to the “/” route so that when a user accesses the site they will be able to view index.html and any assets. In this example we will have an “app.js” file for our JavaScript code and a simple “style.css” for any styling.

func main() {
        // Create a simple file server
        fs := http.FileServer(http.Dir("../public"))
        http.Handle("/", fs)

The next route we want to define is “/ws” which is where we will handle any requests for initiating a WebSocket. We pass it the name of a function called “handleConnections” which we will define later.

func main() {
    ...
        // Configure websocket route
        http.HandleFunc("/ws", handleConnections)

In the next step we start a goroutine called “handleMessages”. This is a concurrent process that will run along side the rest of the application that will only take messages from the broadcast channel from before and the pass them to clients over their respective WebSocket connection. Concurrency in Go is one of it’s greatest features. How it all works is beyond the scope of this article but you can check it out in action for yourself on Go’s official tutorial site. Just think of concurrent processes or goroutines as backround processes or asynchronous functions if you’re familiar with JavaScript.

func main() {
    ...
        // Start listening for incoming chat messages
        go handleMessages()

Finally, we print a helpful message to the console and start the webserver. If there are any errors we log them and exit the application.

func main() {
    ...
        // Start the server on localhost port 8000 and log any errors
        log.Println("http server started on :8000")
        err := http.ListenAndServe(":8000", nil)
        if err != nil {
                log.Fatal("ListenAndServe: ", err)
        }
}

Next we need to create the function to handle our incoming WebSocket connections. First we use the upgrader’s “Upgrade()” method to change our initial GET request to a full on WebSocket. If there is an error, we log it but don’t exit. Also take note of the defer statement. This is neat way to let Go know to close out our WebSocket connection when the function returns. This saves us from writing multiple “Close()” statements depending on how the function returns.

func handleConnections(w http.ResponseWriter, r *http.Request) {
        // Upgrade initial GET request to a websocket
        ws, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
                log.Fatal(err)
        }
        // Make sure we close the connection when the function returns
        defer ws.Close()

Next we register our new client by adding it to the global “clients” map we created earlier.

func handleConnections(w http.ResponseWriter, r *http.Request) {
    ...
        // Register our new client
        clients[ws] = true

The final piece is an inifinite loop that continuously waits for a new message to be written to the WebSocket, unserializes it from JSON to a Message object and then throws it into the broadcast channel. Our “handleMessages()” goroutine can then take it can send it to everyone else that is connected.

If there is some kind of error with reading from the socket, we assume the client has disconnected for some reason or another. We log the error and remove that client from our global “clients” map so we don’t try to read from or send new messages to that client.

Another thing to note is that HTTP route handler functions are run as goroutines. This allows the HTTP server to handle multiple incoming connections without having to wait for another connection to finish.

func handleConnections(w http.ResponseWriter, r *http.Request) {
    ...
        for {
                var msg Message
                // Read in a new message as JSON and map it to a Message object
                err := ws.ReadJSON(&msg)
                if err != nil {
                        log.Printf("error: %v", err)
                        delete(clients, ws)
                        break
                }
                // Send the newly received message to the broadcast channel
                broadcast <- msg
        }
}

The final piece of the server is the “handleMessages()” function. This is simply a loop that continuously reads from the “broadcast” channel and then relays the message to all of our clients over their respective WebSocket connection. Again, if there is an error with writing to the WebSocket, we close the connection and remove it from the “clients” map.

func handleMessages() {
        for {
                // Grab the next message from the broadcast channel
                msg := <-broadcast
                // Send it out to every client that is currently connected
                for client := range clients {
                        err := client.WriteJSON(msg)
                        if err != nil {
                                log.Printf("error: %v", err)
                                client.Close()
                                delete(clients, client)
                        }
                }
        }
}

Building the Client

A chat application wouldn’t be complete without a pretty UI. We’ll create a simple, clean interface using some HTML5 and VueJS. We’ll also take advantage of some libraries like Materialize CSS and EmojiOne for some styling and emoji goodness. Inside the “public” directory, create a new file called “index.html”.

The first piece is pretty basic. We also pull in some stylesheets and fonts to make everything pretty. “style.css” is our own stylesheet to customize a few things.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Simple Chat</title>

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/emojione/2.2.6/assets/css/emojione.min.css"/>
    <link rel="stylesheet" href="/style.css">

</head>

The next piece is just the interface. It’s just a few fields to handle choosing a username and sending messages along with displaying new chat messages. The details of working with VueJS are beyond the scope of this article but check out the documentation if you’re unfamiliar.

<body>
<header>
    <nav>
        <div class="nav-wrapper">
            <a href="/" class="brand-logo right">Simple Chat</a>
        </div>
    </nav>
</header>
<main id="app">
    <div class="row">
        <div class="col s12">
            <div class="card horizontal">
                <div id="chat-messages" class="card-content" v-html="chatContent">
                </div>
            </div>
        </div>
    </div>
    <div class="row" v-if="joined">
        <div class="input-field col s8">
            <input type="text" v-model="newMsg" @keyup.enter="send">
        </div>
        <div class="input-field col s4">
            <button class="waves-effect waves-light btn" @click="send">
                <i class="material-icons right">chat</i>
                Send
            </button>
        </div>
    </div>
    <div class="row" v-if="!joined">
        <div class="input-field col s8">
            <input type="email" v-model.trim="email" placeholder="Email">
        </div>
        <div class="input-field col s8">
            <input type="text" v-model.trim="username" placeholder="Username">
        </div>
        <div class="input-field col s4">
            <button class="waves-effect waves-light btn" @click="join()">
                <i class="material-icons right">done</i>
                Join
            </button>
        </div>
    </div>
</main>
<footer class="page-footer">
</footer>

The last piece is just importing all the required JavaScript libraries to inclue Vue, EmojiOne, jQuery and Materialize. We also need an MD5 library to grab URLs for avatars from Gravatar. This will be explained better when we tackle the JavaScript code. The last import, “app.js”, is our custom code.

<script src="https://unpkg.com/vue@2.1.3/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/emojione/2.2.6/lib/js/emojione.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/md5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script>
<script src="/app.js"></script>
</body>
</html>

Next create a file called “style.css” in the “public” directory. Here we’ll just place a little bit of styling.

body {
    display: flex;
    min-height: 100vh;
    flex-direction: column;
}

main {
    flex: 1 0 auto;
}

#chat-messages {
    min-height: 10vh;
    height: 60vh;
    width: 100%;
    overflow-y: scroll;
}

The final part of the client is our JavaScript code. Create a new file in the “public” directory called “app.js”.

As with any VueJS application we start by creating a new Vue object. We mount it to a div with the id of “#app”. This allows anything within that div to share scope with our Vue instance. Next we define a few variables.

new Vue({
    el: '#app',

    data: {
        ws: null, // Our websocket
        newMsg: '', // Holds new messages to be sent to the server
        chatContent: '', // A running list of chat messages displayed on the screen
        email: null, // Email address used for grabbing an avatar
        username: null, // Our username
        joined: false // True if email and username have been filled in
    },

Vue provides an attribute called “created” which is meant to be a function you define that handles anything you want to as soon as the Vue instance has been created. This is helpful for any setup work you need to do for the application. In this case we want to create a new WebSocket connection with the server and create a handler for when new messages are sent from the server. We store the new WebSocket in our “ws” variable created in the “data” property.

The “addEventListener()” method takes a function that will be used to handle incoming messages. We expect all messages to be a JSON string so we parse it so that it is an object literal. Then we can use the different properties to format a pretty message line complete with an avatar. The “gravatarURL()” method will be explained later. Also we are using a nifty library called EmojiOne to parse emoji codes. The “toImage()” method will turn those emoji codes into actual images. For example if you type “:robot:” it will be replaced with a robot emoji.


    created: function() {
        var self = this;
        this.ws = new WebSocket('ws://' + window.location.host + '/ws');
        this.ws.addEventListener('message', function(e) {
            var msg = JSON.parse(e.data);
            self.chatContent += '<div class="chip">'
                    + '<img src="' + self.gravatarURL(msg.email) + '">' // Avatar
                    + msg.username
                + '</div>'
                + emojione.toImage(msg.message) + '<br/>'; // Parse emojis

            var element = document.getElementById('chat-messages');
            element.scrollTop = element.scrollHeight; // Auto scroll to the bottom
        });
    },

The “methods” property is where we define any functions we would like to use in our VueJS app. The “send” method handles sending messages to the server. First we make sure the message isn’t blank. Then we format the message as an object and then “stringify()” it so that the server can parse it. We use a little jQuery trick to escape HTML and JavaScript from any incoming message. This prevents any sort of injection attacks.

    methods: {
        send: function () {
            if (this.newMsg != '') {
                this.ws.send(
                    JSON.stringify({
                        email: this.email,
                        username: this.username,
                        message: $('<p>').html(this.newMsg).text() // Strip out html
                    }
                ));
                this.newMsg = ''; // Reset newMsg
            }
        },

The “join” function will make sure the user enters an email and username before they can send any messages. Once they do, we set join to “true” and allow them to start chatting. Again we strip out any HTML or JavaScript.


        join: function () {
            if (!this.email) {
                Materialize.toast('You must enter an email', 2000);
                return
            }
            if (!this.username) {
                Materialize.toast('You must choose a username', 2000);
                return
            }
            this.email = $('<p>').html(this.email).text();
            this.username = $('<p>').html(this.username).text();
            this.joined = true;
        },

The final function is a nice little helper function for grabbing the avatar URL from Gravatar. The final piece of the URL needs to be an MD5 encoded string based on the user’s email address. MD5 is a one way encryption algorithm so it helps keep emails private while at the same time allowing the email to be used as a unique identifier.

        gravatarURL: function(email) {
            return 'http://www.gravatar.com/avatar/' + CryptoJS.MD5(email);
        }
    }
});

Running the Application

To run the application, open a console window and make sure you are in the “src” directory of your application then run the following command.

$ go run main.go

Next open a web browser and navigate to “http://localhost:8000“. The chat screen will be displayed and you can now enter an email and username.

To see how the app works with multiple users, just open another browser tab or window and navigate to “http://localhost:8000“. Enter a different email and username. Take turns sending messages from both windows.

Conclusion

This just a basic chat application but there are many more improvements you can make to it. I challenge you to play around with the source code and add some other features, see if you can implement private messaging or notifications when a new user joins or leaves the chat. The sky is the limit!

I hope you found this helpful and are now inspired to start creating your own realtime applications using WebSockets and Go.

Source:: scotch.io

Should You Transform Images On Upload or On Demand?

By chris92

6BzHozJUSZW8Rcn4jYIW_transform-images-on-upload-or-on-demand-cloudinary.png.jpg

As a developer, you hope and anticipate that your website or mobile application will be accessed by different users on various devices. To improve the user-experience, irrespective of the viewing device, you need to make sure that each image adapts to different graphic layouts, device resolutions and other viewing requirements. For example, for an E-Commerce site, one image will be displayed on different pages — home page, product page, shopping cart and more — and will be viewed on a desktop, cellphone or a tablet. This means that you need to create numerous versions of every image and for a website with hundreds of images, manual manipulation is not scalable.

Cloudinary enables you to programmatically transform original images from various sources based on viewing requirements.

Lazy and Eager Transformation

Cloudinary offers multiple strategies for transforming your images. In this article, we’ll discuss two options: “lazy transformations”, which is the default option, and “eager transformations”, which can be selected by adding a flag to the upload API call.

Lazy transformation entails uploading images to Cloudinary as is and then transforming the images only when a user requests the image. The transformation for a given user is performed once, cached and delivered via a CDN for subsequent requests.

This type of transformation is the default option because it limits the bandwidth usage by generating transformations on-demand.

Let’s look at an example:

// Upload image to cloud
cloudinary.v2.uploader.upload('lady.jpg',
    function(error, result) {console.log(result); }
);
// Request image and lazy-transform the image
cloudinary.url("lady.jpg", 
    // Transformation
    {transformation: [
  {width: 400, height: 400, gravity: "face", radius: "max", crop: "crop"}
  ]})

The uploaded image is transformed only when requested with cloudinary.url, which returns a transformed image URL. This is what the request looks like in the network tab:

Even as small as the transformed image is (4.2kb), it still took as much as 976ms to complete the request. Consider how much time it would take if we had up to 50 images that required such transformations on one page of our website. Additionally, customers attempting to access these images during this 1 second in which they are created, will get broken images (error 420) due to concurrent access.

There are cases where, due to highly concurrent access patterns, it is not a good idea to wait until the first access to create the derived image or video. For example, if you run a news site, and tweet about your new article, for thousands of users to access it concurrently, and the images and videos on the article page were not created in advance, many of these users could encounter concurrency issues. In this case, the first user will experience a delay in accessing the images and videos, and while these transformations are being created, rest of the users will get broken images and videos. Reloading the page would fix the problem, but you might lose some users by then.

One way to solve this is to have editors preview their pages before publishing. However, with responsive design, real-time communications, and multiple devices accessing the content, it’s best to make sure the images are created during upload.

Now let’s consider a better solution: Eager transformation.

Eager Transformation

Just as the name states, eager entails transforming images during upload so when the transformations are requested, they will always be optimized and delivered with the best possible performance. So, when a user requests an image, Cloudinary no longer needs to perform transformations on this image because it has already been completed during upload.

With the eager approach, transformation tasks are performed once (during upload) for all requests so users don’t experience any delays.

To perform an eager transformation, use the eager array, which accepts transformation configuration objects:

// Perform transformation while uploading
cloudinary.v2.uploader.upload("lady.jpg", 
    // Eager transformation
    { eager: [
        { width: 400, height: 300, crop: "pad" }, 
        { width: 260, height: 200, crop: "crop", gravity: "north"} ]}, 
    function(error, result) {console.log(result); });

You can pass as many transformation objects as you choose to the eager array. The callback will be executed once the upload and transformation is completed.

You can as well request the image, but this time, you don’t transform:

// Request image without transforming the image
cloudinary.url("lady.jpg");

This is what the request looks like in the network tab:

Let’s consider an image larger in size (22.8k) compared to image in the lazy transformation example. The image request was completed at 469ms, which is about 50 percent faster than the lazy method.

Transforming with API URL

Cloudinary provides a SDK for most of the platforms available today, including .Net, Node, PHP, Ruby, Python, React and Angular. If you want to talk directly to the API, that is possible. For eager transformation, you can use the eager parameter to carry out your actions:

eager=c_crop,w_400,h_400,g_face/w_50,h_50,c_scale|w_30,h_40,c_crop,g_south

The eager parameter receives a list of transformation strings separated with a pipe character (|). Chained transformations are separated with a slash (/).

What Of My Existing Images?

You no doubt have other images already stored on your cloud. It’s possible to use eager transformation on those as well.

Cloudinary allows you to perform explicit transformations on your existing images using the explicit method:

// Update existing image
cloudinary.v2.uploader.explicit('lady', 
      { eager: [
          { width: 200, crop: "scale" }, 
          { width: 360, height: 200, crop: "crop", gravity: "north"} ] }, 
    function(error, result) {console.log(result); } );

The method takes the name of the existing image as the first argument, then options (which transformation is part of) as the second argument and then the callback function to handle the completed update.

Conclusion

Eager transformation delivers better performance, and an improved user experience, while consuming fewer resources. Transformation is just one of the many features you can get from Cloudinary. Learn more.

Source:: scotch.io

Create a MEAN app with Angular 2 and Docker Compose

By ganga

P7m66fISSa2xETXPzVAQ_scotch-featured-image-guidelines.png.jpg

Docker allows us to run applications inside containers. These containers in most cases communicate with each other.

Docker containers wrap a piece of software in a complete filesystem that contains everything needed to run: code, runtime, system tools, system libraries – anything that can be installed on a server. This guarantees that the software will always run the same, regardless of its environment.

We’ll build an angular app in one container, point it to an expressjs api in another container, which connects to MongoDB in another container.

If you haven’t worked with Docker before, this would be a good starting point as we will explain every step covered, in some detail.

Why Use Docker

  1. Docker images usually include only what your application needs to run. As a result, you don’t have to worry about having a whole operating system with things you will never user. This results in smaller images of your application.
  2. Platform Indipendent – I bet you’ve heard of the phrase ‘It worked on my machine, and doesn’t work on the server’. With Docker, all either environments need to have is the Docker Engine, or the Docker Daemon, and when we have a successful build of our image, it should run anywhere.
  3. Once you have an image of your application built, you can easily share the image to anyone who wants to run your application. They need not worry about dependencies, or setting up their indidual environments. All they need to have is Docker Engine installed.
  4. Isolation – You’ll see from the article that I try to separate the individual apps to become indipendent, and only point to each other. The reason behind this is that each part of our entire application should be somewhat indipendent, and scalable on it’s own. Docker in this instance would make scaling these individual parts as easy as spinning up another instance of their images. This concept of building isolated, indipendenlty scalable parts of an entire system is what is called Microservices Approach.You can read more about it in Introduction to Microservices
  5. Docker images usually have tags, referring to their versions. This means you can have versioned builds of your image, enabling you to roll back to a previous version should something unexpected break.

Prerequisites

You need to have docker installed in your setup. Instrutcions for installing docker in your given platform can be found here.

Verify your installation by running

$ docker  -v
Docker version 1.12.3, build 6b644ec

Next, you need to know how to build a simple Angular 2 app and an Express App. We’ll be using the Angular CLI to build a simple app. So install the Angular CLI

$ npm install -g angular-cli

Single Builds Approach

We’ll now separately build out these three parts of our app. The approach we are going to take is building the app in our local environment, then dockerizing the app.

Once these are running, we’ll connect the three docker containers. Note that we are only building two containers, Angular and the Express/Node API. The third container will be from a MongoDB image that we’ll just pull from the Docker Hub.

Docker Hub is a repository for docker images. It’s where we pull down official docker images such as MongoDB, NodeJs, Ubuntu, and we can also create custom images and push them to Docker Hub for other people to pull and use.

Let’s create a directory for our whole set up, we’ll call it mean-docker.

$ mkdir mean-docker

Angular 2 Client App

Next, we’ll create an Angular 2 app and makes sure it runs in a docker container.

Create a directory called angular-client inside the mean-docker directory we created above, and initialize an Angular 2 App with the Angular CLI.

$ mkdir angular-client
$ cd angular-client
$ ng init

This scaffolds and angular app, and npm installs the app’s dependencies. Our directory structure should be like this

└── mean-docker
    └── angular-client
        ├── README.md
        ├── angular-cli.json
        ├── e2e
        ├── karma.conf.js
        ├── node_modules
        ├── package.json
        ├── protractor.conf.js
        ├── src
        └── tslint.json

Running ng serve, inside the angular-client directory should start the angular app at http://localhost:4200.

Dockerizing Angular 2 Client App

To dockerize any app, we usually need to write a Dockerfile

A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image.

To quickly brainstorm on what our angular app needs in order to run,

  1. We need an image with nodejs installed on it
  2. We could have the Angular CLI installed on the image, but the package.json file has it as a dependency, so it’s not a requirement.
  3. We can add our angular app into the image and install it’s dependencies.
  4. It needs to expose port 4200 so that we can access it from our host machine through localhost:4200.
  5. If all these requirements are met, we can run npm start in the container, which in turn runs ng serve since it’s a script in the package.json file, created from the image and our app should run.

Those are the exact instructions we are going to write in our Dockerfile.

mean-docker/angular-client/Dockerfile

# Create image based on the official Node 6 image from dockerhub
FROM node:6

# Create a directory where our app will be placed
RUN mkdir -p /usr/src/app

# Change directory so that our commands run inside this new directory
WORKDIR /usr/src/app

# Copy dependency definitions
COPY package.json /usr/src/app

# Install dependecies
RUN npm install

# Get all the code needed to run the app
COPY . /usr/src/app

# Expose the port the app runs in
EXPOSE 4200

# Serve the app
CMD ["npm", "start"]

I’ve commented on the file to show what each instructions clearly does.

NOTE Before we build the image, if you are keen, you may have noticed that the line COPY . /usr/src/app copies our whole directory into the container, including node_modules. To ignore this, and other files that are irrelevant to our container, we can add a .dockerignore file and list what is to be ignored. This file is usually sometimes identical to the .gitignore file.

Create a .dockerignore file.

mean-docker/angular-client/.dockerignore

node_modules/

One last thing we have to do before building the image, is to ensure that the app is served from the host created by the docker image. To ensure this, go into your package.json and change the start script to.

mean-docker/angular-client/package.json

{
  "scripts": {
    "start": "ng serve -H 0.0.0.0"
  }
}

To build the image we will use docker build command. The syntax is

$ docker build -t <image_tag>:<tag> <directory_with_Dockerfile>

Make sure you are in the mean_docker/angular-client directory, then build your image.

$ cd angular-client
$ docker build -t angular-client:dev .

-t is a shortform of --tag, and refers to the name or tag given to the image to be built. In this case the tag will be angular-client:dev.

The . (dot) at the end refers to current directory. Docker will look for the Dockerfile in our current directory and use it to build an image.

This could take a while depending on your internet connection.

Now that the image is built, we can run a container based on that image, using this syntax

$ docker run -d --name <container_name> -p <host-port:exposed-port>  <image-name>

The -d flag tells docker to run the container in detached mode. Meaning, it will run and get you back to your host, without going into the container.

$ docker run -d --name angular-client -p 4200:4200 angular-client:dev
8310253fe80373627b2c274c5a9de930dc7559b3dc8eef4abe4cb09aa1828a22

--name refers to the name that will be assigned to the container.

-p or --port refers to which port our host machine should point to in the docker container. In this case, localhost:4200 should point to dockerhost:4200, and thus the syntax 4200:4200.

Visit localhost:4200 in your host browser should be serving the angular app from the container.

You can stop the container running with

$ docker stop angular-client

Dockerize the Express Server API

We’ve containerized the angular app, we are now two steps away from our complete set up.

Containerizing a Express app should now be straight forward. Create a directory in the mean-docker directory called express-server.

$ mkdir express-server

Add the following package.json file inside the app.

mean-docker/express-server/package.json

{
  "name": "express-server",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "body-parser": "~1.15.2",
    "express": "~4.14.0"
  }
}

Then, we’ll create a simple express app inside it. Create a file server.js

 $ cd express-serve
 $ touch server.js
 $ mkdir routes && cd routes
 $ touch api.js

mean-docker/express-server/server.js

// Get dependencies
const express = require('express');
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');

// Get our API routes
const api = require('./routes/api');

const app = express();

// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Set our api routes
app.use('/', api);

/**
 * Get port from environment and store in Express.
 */
const port = process.env.PORT || '3000';
app.set('port', port);

/**
 * Create HTTP server.
 */
const server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */
server.listen(port, () => console.log(`API running on localhost:${port}`));

mean_docker/express-server/routes/api.js

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

/* GET api listing. */
router.get('/', (req, res) => {
    res.send('api works');
});

module.exports = router;

This is a simple express app, install the dependencies and start the app.

$ npm install
$ npm start

Going to localhost:3000 in your browser should serve the app.

To run this app inside a docker container, we’ll also create a Dockerfile for it. It should be pretty similar to what we already have for the angular-client.

mean-docker/express-server/Dockerfile

 # Create image based on the official Node 6 image from the dockerhub
FROM node:6

# Create a directory where our app will be placed
RUN mkdir -p /usr/src/app

# Change directory so that our commands run inside this new directory
WORKDIR /usr/src/app

# Copy dependency definitions
COPY package.json /usr/src/app

# Install dependecies
RUN npm install

# Get all the code needed to run the app
COPY . /usr/src/app

# Expose the port the app runs in
EXPOSE 3000

# Serve the app
CMD ["npm", "start"]

You can see the file is pretty much the same as the angular-client Dockerfile, except for the exposed port.

We can then build image and run a container based on the image with.

$ docker build -t express-server:dev .
$ docker run -d --name express-server -p 3000:3000 express-server:dev

Going to localhost:3000 in your browser should serve the api.

Once you are done, you can stop the container with

$ docker stop express-server

MongoDB container

The last part of our MEAN set up, before we connect them all together is the MongoDB. Now, we can’t have a Dockerfile to build a MongoDB image, because on already exists from the Docker Hub. We only need to know how to run it.

Assuming we had a MongoDB image already, we’d run a container based on the image by

$ docker run -d --name mongodb -p 27017:27017 mongo

The image name in this instance is mongo, the last parameter, and the container name will be mongodb.

Docker will check to see if you have a mongo image already downloaded, or built. If not, it will look for the image in the Dockerhub. If you run the above command, you should have mongodb instance running inside a container.

To check if mongodb is running, simply go to http://localhost:27017 in you browser, and you should see this message. It looks like you are trying to access MongoDB over HTTP on the native driver port.

Alternatively, if you have mongo installed in your host machine, simply run mongo in the terminal. And it should run and give you the mongo shell, without any errors.

Docker Compose

To connect and run multiple containers with docker, we use Docker Compose.

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a Compose file to configure your application’s services. Then, using a single command, you create and start all the services from your configuration.

Docker compose is usually installed when you install docker. So to simply check if you have it installed, run

$ docker-compose

You should see a list of commands from docker-compose. If not, you can go through the installation here

Create a docker-compose.yml file in the root of our set up.

$ touch docker-compose.yml

Our directory tree should now look like this.

.
├── angular-client
├── docker-compose.yml
└── express-server

Then edit the docker-compose.yml file

mean-docker/docker-compose.yml

version: '2' # specify docker-compose version

# Define the services/containers to be run
services:
  angular: # name of the first service
    build: angular-client # specify the directory of the Dockerfile
    ports:
      - "4200:4200" # specify port forewarding

  express: #name of the second service
    build: express-server # specify the directory of the Dockerfile
    ports:
      - "3000:3000" #specify ports forewarding

  database: # name of the third service
    image: mongo # specify image to build container from
    ports:
      - "27017:27017" # specify port forewarding

The docker-compose.yml file is a simple configuration file telling docker compose which continers to build. That’s pretty much it.

Now, to run containers based on the three images, simply run

$ docker-compose up

This will build the images if not already built, and run them. Once it’s running, and your terminal looks something like this.

You can visit all the three apps, http://localhost:4200, http://localhost:3000 or http://localhost:27017, and you’ll see that all the three containers are running.

Connecting the 3 Docker containers

Finally, the fun part.

Express and MongoDb

We now finally need to connect the three containers. We’ll first create a simple CRUD feature in our api using mongoose. You can go through Easily Develop Node.js and MongoDB Apps with Mongoose to get a more detailed explanation of mongoose.

First of all, add mongoose to your express server package.json

mean-docker/express-server/package.json

{
  "name": "express-server",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "body-parser": "~1.15.2",
    "express": "~4.14.0",
    "mongoose": "^4.7.0"
  }
}

We need to update our api to use mongo

mean-docker/express-server/routes/api.js

// Import dependencies
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();

// MongoDB URL from the docker-compose file
const dbHost = 'mongodb://database/mean-docker';

// Connect to mongodb
mongoose.connect(dbHost);

// create mongoose schema
const userSchema = new mongoose.Schema({
  name: String,
  age: Number
});

// create mongoose model
const User = mongoose.model('User', userSchema);

/* GET api listing. */
router.get('/', (req, res) => {
        res.send('api works');
});

/* GET all users. */
router.get('/users', (req, res) => {
    User.find({}, (err, users) => {
        if (err) res.status(500).send(error)

        res.status(200).json(users);
    });
});

/* GET one users. */
router.get('/users/:id', (req, res) => {
    User.findById(req.param.id, (err, users) => {
        if (err) res.status(500).send(error)

        res.status(200).json(users);
    });
});

/* Create a user. */
router.post('/users', (req, res) => {
    let user = new User({
        name: req.body.name,
        age: req.body.age
    });

    user.save(error => {
        if (error) res.status(500).send(error);

        res.status(201).json({
            message: 'User created successfully'
        });
    });
});

module.exports = router;

Two main differences, first of all our connection to mongo db is in the line const dbHost = 'mongodb://database/mean-docker';. This database is the same as the database service we created in the docker-compose file.

We’ve also added rest routes GET /users, GET /users/:id and POST /user.

Update the docker-compose file, telling the express service to link to the database service.

mean-docker/docker-compose.yml

version: '2' # specify docker-compose version

# Define the services/containers to be run
services:
  angular: # name of the first service
    build: angular-client # specify the directory of the Dockerfile
    ports:
      - "4200:4200" # specify port forewarding

  express: #name of the second service
    build: express-server # specify the directory of the Dockerfile
    ports:
      - "3000:3000" #specify ports forewarding
    links:
      - database # link this service to the database service

  database: # name of the third service
    image: mongo # specify image to build container from
    ports:
      - "27017:27017" # specify port forewarding

The links property of the docker-compose file creates a connection to the other service with the name of the service as the host name. In this case database will be the hostname. Meaning, to connect to it frrom the express service, we should use database:27017. That’s why we made the dbHost equal to mongodb://database/mean-docker.

Angular 2 and Express

The last part is to connect the Angular app to the express server. To do this, we’ll need to make some modifications to our angular 2 app to consume the express api.

mean-docker/angular-client/src/app/app.component.ts

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';

// Import rxjs map operator
import 'rxjs/add/operator/map';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'app works!';

  // Link to our api, pointing to localhost
  API = 'http://localhost:3000';

  // Declare empty list of people
  people: any[] = [];

  constructor(private http: Http) {}

  // Angular 2 Life Cycle event when component has been initialized
  ngOnInit() {
    this.getAllPeople();
  }

  // Add one person to the API
  addPerson(name, age) {
    this.http.post(`${this.API}/users`, {name, age})
      .map(res => res.json())
      .subscribe(() => {
        this.getAllPeople();
      })
  }

  // Get all users from the API
  getAllPeople() {
    this.http.get(`${this.API}/users`)
      .map(res => res.json())
      .subscribe(people => {
        console.log(people)
        this.people = people
      })
  }
}

Angular 2 style guides usually recommends separating most logic into a service/provider. We’ve placed all the code in the component here for brevity.

We’ve imported the OnInit interface, to call events when the component is initialized, then added a two methods AddPerson and getAllPeople, that call the API.

Notice that this time round, our API is pointing to localhost. This is because while the angular 2 app will be running inside the container, it’s served to the browser. And the browser is the one that makes request. It will thus make a request to the exposed express API. As a result, we don’t need to link Angular and Express in the docker-compose.yml file.

Next, we need to make some changes to the template. I first added bootstrap via cdn to the index.html

mean-docker/angular-cli/src/app/index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Angular Client</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- Bootstrap CDN -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css">

  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root>Loading...</app-root>
</body>
</html>

Then update the app.component.html template

mean-docker/angular-client/src/app/app.component.html

<!-- Bootstrap Navbar -->
<nav class="navbar navbar-light bg-faded">
  <div class="container">
    <a class="navbar-brand" href="#">Mean Docker</a>
  </div>
</nav>

<div class="container">
  <div [style.margin-top.px]="10" class="row">
    <h3>Add new person</h3>
    <form class="form-inline">
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" #name>
      </div>
      <div class="form-group">
        <label for="age">Age</label>
        <input type="number" class="form-control" id="age" #age>
      </div>
      <button type="button" (click)="addPerson(name.value, age.value)" class="btn btn-primary">Add person</button>
    </form>
  </div>
  <div [style.margin-top.px]="10" class="row">
    <h3>People</h3>
    <!-- Bootstrap Card -->
    <div [style.margin-right.px]="10" class="card card-block col-md-3" *ngFor="let person of people">
      <h4 class="card-title">{{person.name}}  {{person.age}}</h4>
    </div>
  </div>
</div>

The above template shows the components properties and bindings. We are almost done.

Since we’ve made changes to our code, we need to do a build for our Docker Compose

$ docker-compose up --build

The --build flag tells docker compose that we’ve made changes and it needs to do a clean build of our images.

Once this is done, go to localhost:4200 in your browser,

We are getting a No 'Access-Control-Allow-Origin' error. To quickly fix this, we need to enable Cross-Origin in our express app. We’ll do this with a simple middleware.

mean-docker/express-server/server.js

// Code commented out for brevity

// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Cross Origin middleware
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*")
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
  next()
})

// Set our api routes
app.use('/', api);

// Code commented out for brevity

We can now run docker-compose again with the build flag. You should be in the mean-docker directory

$ docker-compose up --build

Going to localhost:4200 on the browser.

Conclusion

I bet you’ve learned a thing or two about MEAN or docker and docker-compose.

The problem with our set up however is that any time we make changes to either the angular app, or the express api, we need to run docker-compose up --build.

This can get tidious or even boring over time. We’ll look at this in the another article.

Source:: scotch.io

React Universal with Next.js: Server-side React

By chris92

pMGOpicdSeydAgvHREUA_react-universal-with-next-js-react-server-side-rendering.png.jpg

The term “universal” is a community-coined term for building web apps that render happily on a server. You might be familiar with “isomorphic” as well but the goal of this article is not to debate names; we are going to learn how to build server-rendered React apps with Next.js.

We’ve talked about building React server-side before. Today we’ll discuss the topic more since it’s an important one.

Why Build Universal Apps.

React apps implement the virtual DOM ideology which is an abstraction of the real/original DOM. This abstraction is very useful to app performance because we can take a portion of the DOM, bind whatever data we need to bind, and insert back to the original DOM tree. This is in no way standardized and is just a concept that front-end frameworks utilize to make better user experience a true story.

Just as every great thing comes with a price, Virtual DOM poses a problem. The original DOM which was received based on some information provided by the server has been lost. You might be wondering why that matters — it does and we will see how.

Search Engines do not care about how your app is architected or whatever ideology was used so as to adjust and fetch the right content. Their bots are not as smart as using your apps like a real user would. All they care about is that once they send their spiders to crawl and index your site, whatever the server provides on the first request is what gets indexed. That is bad news because at that time your app lacks the actual content on the server. This is what the spider takes home from your website:

React Server-side Preview

Preview

React Server-side Preview

Source

Things even get worst when you try to share your app on a social media platform like Facebook or Twitter. You are going to end up with an unexpected behavior because your actual content is not loaded on the server, it’s just the entry point (probably the content of some index.html) that is.

How do we tackle these problems?

Go Universal with Next.js

Universal apps are architected in such manner that your app renders both on the client and the server. In React’s case, the virtual DOM is eventually dropped on the server as well as using some mechanisms that might give you headache if you don’t choose the right tool.

I have worked with few solutions but Next.js it is very promising. Next is inspired by the 7 Principles of Rich Applications. The idea is to have a good experience while using web app as well as building it. The experience should feel natural.

Next offers more out of the box:

  • No configuration or additional setup
  • Easy component and global style with Glamor
  • Automatic transpilation and bundling (with webpack and babel)
  • Hot code reloading
  • Static file serving. ./static/ is mapped to /static/
  • Route prefetching. Coming soon

DEMO: Barclays Premier League Table

Let’s do something fun with Next.js together. We will use the Football Data API to build a simple small app that shows the Barclays Premier League ranking table. If that sounds like fun to you, then let’s get started.

Prerequisites

Developers hate long stories when it comes to setting up a new project. Worry not, Next.js is just an npm package and all you need do is install locally and start building your app:

# Start a new project
npm init
# Install Next.js
npm install next --save

Once the installation is completed, you can update the start script to run next:

"scripts": {
   "start": "next"
 },

The Next installation installs React as well so no need to do that again. All you need to do now to put a server-rendered web page out there is to create a pages directory in the root of the app and add an index.js file:

// ./pages/index.js

// Import React
import React from 'react'

// Export an anonymous arrow function
// which returns the template
export default () => (
  <h1>This is just so easy!</h1>
)

Now run the following command to see your app running at localhost:3000:

# Start your app
npm start

Preview

Source

I bet this was easier than you even expected. You have a running app in about 5 minutes that is server-rendered. We are making history!

Page Head

We can add a head section in the page so as to define global styles and set meta details:

// ./pages/index.js
import React from 'react'
// Import the Head Component
import Head from 'next/head'

export default () => (
  <div>
    <Head>
        <title>League Table</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
        <link rel="stylesheet" href="https://unpkg.com/purecss@0.6.1/build/pure-min.css" />
    </Head>
    <h1>This is just so easy!</h1>
  </div>
)

The Head component which is provided by Next is used to attach head to the DOM of a page. We just wrap the supposed head DOM content in Head Next component.

Ajax Requests

Next provides a getInitialProps which can be used with async (optional) which assists in performing async operations. You can use the await keyword to handle operations that are deferred. See the following example:

import React from 'react'
import Head from 'next/head'
import axios from 'axios';

export default class extends React.Component {
    // Async operation with getInitialProps
    static async getInitialProps () {
        // res is assigned the response once the axios
        // async get is completed
        const res = await axios.get('http://api.football-data.org/v1/competitions/426/leagueTable');
        // Return properties
        return {data: res.data}
      }
 }

We are using the axios library to carry out HTTP requests. The requests are asynchronous so we need a way to catch the response in the future when it is available. With async...await, we can actual handle the async request without having to use callbacks or chain promises.

We pass the value to props by returning an object which properties can be accessed from the props like this.props.data:

import React from 'react'
import Head from 'next/head'
import axios from 'axios';

export default class extends React.Component {
  static async getInitialProps () {
    const res = await axios.get('http://api.football-data.org/v1/competitions/426/leagueTable');
    return {data: res.data}
  }
  render () {
    return (
      <div>
        <Head>
            <title>League Table</title>
            <meta name="viewport" content="initial-scale=1.0, width=device-width" />
            <link rel="stylesheet" href="https://unpkg.com/purecss@0.6.1/build/pure-min.css" />
        </Head>
        <div className="pure-g">
            <div className="pure-u-1-3"></div>
            <div className="pure-u-1-3">
              <h1>Barclays Premier League</h1>
              <table className="pure-table">
                <thead>
                  <tr>
                    <th>Position</th>
                    <th>Team</th>
                    <th>P</th>
                    <th>GL</th>
                    <th>W</th>
                    <th>D</th>
                    <th>L</th>
                  </tr>
                </thead>
                <tbody>
                {this.props.data.standing.map((standing, i) => {
                  const oddOrNot = i % 2 == 1 ? "pure-table-odd" : "";
                  return (
                      <tr key={i} className={oddOrNot}>
                        <td>{standing.position}</td>
                        <td><img className="pure-img logo" src={standing.crestURI}/></td>
                        <td>{standing.points}</td>
                        <td>{standing.goals}</td>
                        <td>{standing.wins}</td>
                        <td>{standing.draws}</td>
                        <td>{standing.losses}</td>
                      </tr>
                    );
                })}
                </tbody>
              </table>
            </div>
            <div className="pure-u-1-3"></div>
        </div>
      </div>
    );
  }
}

React Universal App Progress

We can now bind the data to the rendered template by iterating over the standing property on the data and printing each of the standings. The class names are as a result of the Pure CSS style included in the head which is a very simple CSS library to get you started.

Routing

You might not be aware but we already have routes in our application. Next does not require any additional configuration to setup routing. You just keep adding routes as pages to the pages directory. Let’s create another route to show more details about a team:

// ./pages/details.js
import React from 'react'
export default () => (
  <p>Coming soon. . .!</p>
)

You can navigate from one route to another using the Link component from Next:

// ./pages/details.js
import React from 'react'

// Import Link from next
import Link from 'next/link'

export default () => (
  <div>
      <p>Coming soon. . .!</p>
      <Link href="/">Go Home</Link>
  </div>
)

It’s time to update the details page to display more information about a given team. The team’s position will be passed as a query parameter, id, to the page. The id will be used to then filter the team’s information:

import React from 'react'
import Head from 'next/head'
import Link from 'next/link'
import axios from 'axios';

export default class extends React.Component {
    static async getInitialProps ({query}) {
        // Get id from query
        const id = query.id;
        if(!process.browser) {
            // Still on the server so make a request
            const res = await axios.get('http://api.football-data.org/v1/competitions/426/leagueTable')
            return {
                data: res.data,
                // Filter and return data based on query
                standing: res.data.standing.filter(s => s.position == id)
            }
        } else {
            // Not on the server just navigating so use
            // the cache
            const bplData = JSON.parse(sessionStorage.getItem('bpl'));
            // Filter and return data based on query
            return {standing: bplData.standing.filter(s => s.position == id)}
        }
    }

    componentDidMount () {
        // Cache data in localStorage if
        // not already cached
        if(!sessionStorage.getItem('bpl')) sessionStorage.setItem('bpl', JSON.stringify(this.props.data))
    }

    // . . . render method truncated
 }

This page displays dynamic content based on the query parameter. We receive the query from the getInitialProps and then use the id value to filter the data array from a given team based on their position on the table.

The most interesting aspect of the above logic is that we are not requesting data more than once in the app’s lifecycle. Once the server renders, we fetch the data and cache it with sessionStorage. Subsequent navigation will be based on the cached data. sessionStorage is preferred to localStorage because the data will not persist once the current window exits.

The storage is done using componentDidMount and not getInitialProps because when getInitialProps is called, the browser is not prepared so sessionStorage is not known. For this reason, we need to wait for the browser and a good way to catch that is with componentDidMount React lifecycle method. getInitialProps is said to be isomorphic.

Let’s now render to the browser:

// . . . truncated

export default class extends React.Component {
    // . . . truncated
    render() {

        const detailStyle = {
            ul: {
                marginTop: '100px'
            }
        }

        return  (
             <div>
                <Head>
                    <title>League Table</title>
                    <meta name="viewport" content="initial-scale=1.0, width=device-width" />
                    <link rel="stylesheet" href="https://unpkg.com/purecss@0.6.1/build/pure-min.css" />
                </Head>

                <div className="pure-g">
                    <div className="pure-u-8-24"></div>
                    <div className="pure-u-4-24">
                        <h2>{this.props.standing[0].teamName}</h2>
                        <img src={this.props.standing[0].crestURI} className="pure-img"/>
                        <h3>Points: {this.props.standing[0].points}</h3>
                    </div>
                    <div className="pure-u-12-24">
                        <ul style={detailStyle.ul}>
                            <li><strong>Goals</strong>: {this.props.standing[0].goals}</li>
                            <li><strong>Wins</strong>: {this.props.standing[0].wins}</li>
                            <li><strong>Losses</strong>: {this.props.standing[0].losses}</li>
                            <li><strong>Draws</strong>: {this.props.standing[0].draws}</li>
                            <li><strong>Goals Against</strong>: {this.props.standing[0].goalsAgainst}</li>
                            <li><strong>Goal Difference</strong>: {this.props.standing[0].goalDifference}</li>
                            <li><strong>Played</strong>: {this.props.standing[0].playedGames}</li>
                        </ul>
                        <Link href="/">Home</Link>
                    </div>
                </div>
             </div>
            )
    }
}

Our index page does not implement this performance related feature in details page. We can update the component accordingly:

// . . . imports truncated

export default class extends React.Component {
  static async getInitialProps () {
    if(!process.browser) {
      const res = await axios.get('http://api.football-data.org/v1/competitions/426/leagueTable')
      return {data: res.data}
    } else {
      return {data: JSON.parse(sessionStorage.getItem('bpl'))}
    }
  }

  componentDidMount () {
    if(!sessionStorage.getItem('bpl')) sessionStorage.setItem('bpl', JSON.stringify(this.props.data))
  }
  // . . . render method truncated
}

The index template should also be updated to include links that point to each team’s details page:

// . . . some imports truncated
import Link from 'next/link'

export default class extends React.Component {
 // . . . truncated
  render () {
    const logoStyle = {
      width: '30px'
    }

    return (
      <div>
        <Head>
            <title>League Table</title>
            <meta name="viewport" content="initial-scale=1.0, width=device-width" />
            <link rel="stylesheet" href="https://unpkg.com/purecss@0.6.1/build/pure-min.css" />
        </Head>
        <div className="pure-g">
            <div className="pure-u-1-3"></div>
            <div className="pure-u-1-3">
              <h1>Barclays Premier League</h1>

              <table className="pure-table">
                <thead>
                  <tr>
                    <th>Position</th>
                    <th>Team</th>
                    <th>P</th>
                    <th>GL</th>
                    <th>W</th>
                    <th>D</th>
                    <th>L</th>
                    <th></th>
                  </tr>
                </thead>
                <tbody>
                {this.props.data.standing.map((standing, i) => {
                  const oddOrNot = i % 2 == 1 ? "pure-table-odd" : "";
                  return (
                      <tr key={i} className={oddOrNot}>
                        <td>{standing.position}</td>
                        <td><img className="pure-img logo" src={standing.crestURI} style={logoStyle}/></td>
                        <td>{standing.points}</td>
                        <td>{standing.goals}</td>
                        <td>{standing.wins}</td>
                        <td>{standing.draws}</td>
                        <td>{standing.losses}</td>
                        <td><Link href={`/details?id=${standing.position}`}>More...</Link></td>
                      </tr>
                    );
                })}
                </tbody>
              </table>
            </div>
            <div className="pure-u-1-3"></div>
        </div>
      </div>
    );
  }
}

Error Pages

You can define custom error pages by creating a _error.js page to handle 4 and 5 errors. Next already displays errors so if that is fine with you, then no need to create the new error page.

// ./pages/_error.js
import React from 'react'

export default class Error extends React.Component {
  static getInitialProps ({ res, xhr }) {
    const statusCode = res ? res.statusCode : (xhr ? xhr.status : null)
    return { statusCode }
  }

  render () {
    return (
      <p>{
        this.props.statusCode
        ? `An error ${this.props.statusCode} occurred on server`
        : 'An error occurred on client'
      }</p>
    )
  }
}

This is what a 404 looks like with the default error page:

React Universal 404

…but with the custom error page, you get:

Deploying

Next is always production ready at all time. Let’s deploy to now to see how simple deploying is. First install now:

npm install -g now

You need to get an account by downloading the desktop app

Update the scripts in package.json to include a build command for our app:

"scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },

Now run the build and start command to prepare for deploying:

# Build
npm run build
# Start
npm start

You can just deploy by running now:

now

Additional Resources

Source:: scotch.io

How-to Create and Provide a Dialog Which Will Get You Clients

By Rashmi Chatterjee

Subscribe in a reader

Many businesses give you the 1st part of An Example article. Leading large quality firms don’t generally give you a whole Test composition. Occasionally though, merely a portion of An Example essay might help you. In instances in this way, it really is fine to apply a part of the test article. It’s possible to obtain just about any Sample article on the web for different themes. There is no need to buy a Sample essay, since it’s entirely free. Essay writing is frequently a daunting employment to lots of men and women. The paragraph is really not a outline of what it’s you’re writing about, rather, it’s in support of what you are authoring. Before starting, you can find some things you should be aware of about writing an essay.

File at the least 1 to 3 more occasions.

Writers of analytic documents have to get enough advice regarding the material they might be currently talking about. Irrespective of if you’re composing an essay for 2nd custom essay writing online grade pupils or you are distributing this as a section of your Ph.D. dissertation, you are required to follow this arrangement constantly. The human body supplies the info that facilitates what’s said within the introduction together with in the very first word of the paragraph. When composing your analytical article it helps you to really invigorate your thoughts because you’ll manage to examine each of the significant characteristics of the item you’re writing about. Before beginning to write the thesis statement, make an outline of your own essay subsequently take the critical notion which you will present within the article to make your thesis statement. One particular frequent mistake that lots of people do while writing it, is creating an entire statement about what they’re going to write within the article. Let’s take a glance at the critical points that need to be held in mind whilst composing a dissertation declaration, alongside a couple types of thesis statements.

Without it, madison presumed that the u.s.

Do not forget to follow the particular order of reason within the body of your own article as stated in your thesis statement. One should comprehend the 3 conventional sections of the essay. Here ‘s the whole essay. Writing analytic documents isn’t an effortless endeavor and therefore pupils have to get support from online article writing firms. First, let us have a look at the start of the essay. When you’ve assembled the information, begin together with the introduction. Think of your own opening for a map of your own essay, or perhaps for a guide. On the opposite hand, there might be a quandary where you will be bound to compose a sample paper.

And if they are, it???s simple to balance them.something you can certainly do is weight training.

They’re part of the training and so they need to write quality argumentative article to be able to get enhanced mark within their assessments. It’s the kind of papers you’d compose before writing a option paper. In any case, the actual objective of a sample document is for the clear-cut objective of viewing. Usually, you will contend powerfully for the vital trigger in this sort of article. In the subsequent post, we’ll look into the argumentative essay describe in detail and strive to get how an ideal argumentative essay must be written. It is going to house the primary content of the essay. This can make the fundamental skeleton and abstract of your own article.

http://www.phloxblog.in/feed/

Source:: phloxblog.in

Steps to Make a Title Page for a Research-Paper

By Rashmi Chatterjee

Subscribe in a reader

Our essays for sale are totally unique and exclusive. Observe the Penguin Publications Web Site for added details about the way the documents should be submitted. The six finalists inside the article competition. Before you go into the article contest, make certain to ‘re ready to pay the $150 accessibility price The composition may be amazing narrative or it may possibly control the atmosphere, governmental activism, history or nature. By American standards the story is perhaps a tragedy, but it usually does not follow the regular structure with this type. Demo you’ve researched the issue extensively. Read the absolute story at Mashable.

Definitely, it is that essential.

Write your article inside an easyto – comprehend format. Do not use Wikipedia or dictionary meanings within your composition. A. Your essay may never be considered. Keep these ideas in your mind the following time you write an essay. FreelanceWriting features a document write my essay of innovative writing contests without an entry fees. Click here to find out more about the procedure prizes and to detect the admittance form for the competition. Be aware of terminology indicating the competition patron may apply your entrance for goals besides publicity.

Organize your additional reports to find out if you want bright dividers.

Following are a few tips to permit you to value contests. Certain guidelines for entries are supplied on the webpage for every contest as specified below. They ought to be delivered in one bundle with one search for the right sum. Creating competitions are an excellent solution to convey your imagination when winning good awards. Contest winners are chosen through the yr.

http://www.phloxblog.in/feed/

Source:: phloxblog.in