What is Fastify?
In the rapidly evolving world of web development, developers are constantly on the lookout for frameworks that can provide both speed and efficiency. Enter Fastify, a lightweight and lightning-fast web framework for Node.js that has taken the development community by storm. If you’re a developer looking to create high-performance, scalable, and secure web applications, Fastify may be the game-changer you’ve been waiting for.
What is Fastify?
Fastify, developed by Matteo Collina and Tomas Della Vedova, is an open-source web framework for Node.js designed with a primary focus on speed and low overhead. Launched in 2016, Fastify has quickly gained popularity in the Node.js ecosystem due to its impressive performance, simplicity, and extensibility. It is built on top of Node.js’s HTTP module and takes full advantage of the latest JavaScript features to maximize its speed and efficiency.
Getting started with Fastify:
- npm init
- npm i fastify
- Required minimum node.js version of node 14.
- In express js return JSON data using res.json({ hello: “world” }) function but fastify no need to json function.
// Require the framework and instantiate it const fastify = require("fastify")({ logger: true }); // Declare a rout fastify.get("/", async (request, reply) => { return { hello: "world" }; }); // Start the server fastify.listen(3000);
Fastify comes with amazing set of features which will give boost to your project:
The Need for Speed
One of the primary reasons developers are flocking to Fastify is its exceptional performance. Thanks to its powerful and highly optimized core, Fastify boasts some of the fastest request/response times among Node.js frameworks. It leverages features like request validation, which is automatically generated from JSON schemas, to ensure that data is processed swiftly and accurately. Additionally, Fastify supports asynchronous programming and handles requests concurrently, making it ideal for handling heavy workloads and high traffic.
Minimalism and Extensibility
Fastify follows a minimalist approach, focusing on providing only the essential components needed to build web applications efficiently. Developers can opt-in to use various plugins to extend Fastify’s functionality as per their requirements. This approach not only keeps the core lightweight but also gives developers the flexibility to customize their stack with the specific tools they need. Furthermore, the ecosystem around Fastify is growing rapidly, with a wide array of plugins and middleware available, making it easy to integrate third-party tools seamlessly.
Developer-Friendly API
Fastify’s API is designed to be intuitive and easy to use, reducing the learning curve for developers. Its well-documented and expressive API allows developers to write clean, maintainable, and organized code. The framework’s emphasis on proper error handling and logging also contributes to its ease of use, helping developers quickly identify and rectify issues during development and production.
JSON Schema-Based Validation
Data validation is a crucial aspect of web application development to ensure data integrity and security. Fastify utilizes JSON Schema for data validation, enabling developers to define the expected shape of incoming requests and responses. This not only simplifies the validation process but also automatically generates detailed and helpful error messages, making debugging a breeze.
Enhanced Security
Fastify is designed with security in mind. It encourages best practices such as using the latest cryptographic libraries and secure authentication mechanisms. Additionally, Fastify has a built-in protection mechanism against common web application attacks like Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF). With Fastify, developers can rest assured that their applications are less prone to security vulnerabilities.
Conclusion
Fastify’s emergence as a top-tier web framework for Node.js is no coincidence. Its commitment to speed, minimalism, and extensibility sets it apart from the competition. Whether you’re building a small-scale API or a large-scale application, Fastify’s performance, easy-to-use API, and emphasis on security make it an excellent choice.
In the fast-paced world of web development, having a framework that can boost productivity and deliver top-notch performance is essential. Fastify has proven itself as a reliable and efficient framework, providing developers with the tools they need to create high-performance applications without compromising on code quality and security.
So, if you’re ready to take your Node.js projects to the next level, give Fastify a try, and experience the speed and power it brings to your development workflow.
For more information and to develop web applications using Node.js, Hire Node.js Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft”.
To develop custom web apps using Node.js, please visit our technology page.
Content Source:
- fastify.dev
How to write smarter routing using Express and Node.js
Express is a web application framework for Node. It provides various features that make web-application development fast and easy, a task that otherwise takes more time when using only Node.
There are many ways you can create and manage routes using Express, the most simple and direct being through the use of the delete, get, post, and put methods. Each one of them is mapped to the equivalent request HTTP verb.
const express = require("express"); const app = express(); const port = 3000; app.get("/", (req, res) => res.send("GET")); app.post("/", (req, res) => res.send("POST")); app.get("/home", (req, res) => res.send("GET HOME")); app.post("/home", (req, res) => res.send("POST HOME")); app.get("/about", (req, res) => res.send("GET HOME")); app.post("/about", (req, res) => res.send("POST HOME")); app.listen(port, () => console.log(`App listening at http://localhost:${port}`) );
In the example above, we have three routes (/, /home, /about), each one with two different HTTP verbs (get, post) and its own logic that’s sending a unique text to the client
As you can see from this tiny example, this kind of approach can get very messy when the number of routes increase.
There’s a way we can make this code better by using the route method and method chaining to equal paths:
const express = require("express"); const app = express(); const port = 3000; app.route("/") .get((req, res) => res.send("GET")) .post((req, res) => res.send("POST")); app.route("/home") .get((req, res) => res.send("GET HOME")) .post((req, res) => res.send("POST HOME")); app.route("/about") .get((req, res) => res.send("GET HOME")) .post((req, res) => res.send("POST HOME")); app.listen(port, () => console.log(`App listening at http://localhost:${port}`) );
This way we can make the code a little bit shorter, but it’s still messy since we have multiple route paths in the same file.
Our next step is to create a separate file for each path and make use of the Express Router object. The Router object is an isolated instance of middleware and routes. You can think of it as a mini-application, capable only of performing middleware and routing functions.
// /routes/root.js const express = require("express"); const router = express.Router(); router .route("/") .get((req, res) => res.send("GET")) .post((req, res) => res.send("POST")); module.exports = router; // /routes/home.js const express = require("express"); const router = express.Router(); router .route("/") .get((req, res) => res.send("GET HOME")) .post((req, res) => res.send("POST HOME")); module.exports = router; // /routes/about.js const express = require("express"); const router = express.Router(); router .route("/") .get((req, res) => res.send("GET ABOUT")) .post((req, res) => res.send("POST ABOUT")); module.exports = router; // index.js const express = require("express"); const app = express(); const port = 3000; app.use("/", require("./routes/root")); app.use("/home", require("./routes/home")); app.use("/about", require("./routes/about")); app.listen(port, () => console.log(`App listening at http://localhost:${port}`) );
This way, we have cleaner code in the main file, index.js, and each route is defined in its own file. In addition to the Route object, we make use of the Express method use to map the path to its configuration file.
It’s much better than what we had in the earlier examples, but we can still see some problems here — like the code repetition in each route file and, mainly, the fact that every time we add new route files to the app, we need to change the main file to map the path to the file. When we have a great number of routes, we have the same problem: The main file code gets bigger and messy.
To solve the second issue, we can make a separate file to map each path to its route file and do a simple require in the main file.
// /routes/index.js module.exports = (app) => { app.use("/", require("./root")); app.use("/home", require("./home")); app.use("/about", require("./about")); }; // index.js const express = require("express"); const app = express(); const port = 3000; require("./routes")(app); app.listen(port, () => console.log(`App listening at http://localhost:${port}`) );
The routes folder index file receives the app instance from the main file and makes the path mapping. The main file makes use of the Immediately Invoked Function Expression to require and execute the routes index file passing the app created. Now we have a cleaner main file, but we still have the problem that it’s required to manually map each path to its file.
Node can help us make this better if we can make it loop through the routes folder’s files and make the mapping. To achieve this, we’ll make use of Node’s fs.readdirSync. This method is used to synchronously read the contents of a given directory. The method returns an array with all the file names or objects in the directory.
And you may ask, what about the path? If we don’t have an automated way to discover the path of each route file, we’ll still have to edit the list for each route added. We can see two kinds of solutions for this issue: to use convention over configuration or to add a export with the path in the route file.
To use convention over configuration, we’ll use the filename as the route path. To make it safer and to remove potential problematic characters, we’ll use Lodash to convert the filename to snakeCase, where strings are separated by an underscore.
Another change we’ll make is to use the Router object only in the routes config file, making the route code simpler and avoiding code repetition.
Besides this, we’ll make use the path.join Node method to make our code cross-platform, since Windows and Linux-based systems use different path names:
// /routes/root.js module.exports = (router) => { router .get("/", (req, res) => res.send("GET")) .post("/", (req, res) => res.send("POST")); return router; }; // /routes/home.js module.exports = (router) => { router .get("/", (req, res) => res.send("GET HOME")) .post("/", (req, res) => res.send("POST HOME")); return router; }; // /routes/about.js module.exports = (router) => { router .get("/", (req, res) => res.send("GET ABOUT")) .post("/", (req, res) => res.send("POST ABOUT")); return router; }; // routes/index.js const snakeCase = require("lodash/snakeCase"); const express = require("express"); module.exports = (app) => { require("fs") .readdirSync(__dirname) .forEach((file) => { if (file === "index.js") return; const path = "/" + (file !== "root.js" ? snakeCase(file.replace(".js", "")) : ""); // root.js file will map to / const router = express.Router(); const route = require(require("path").join(__dirname, file));(router); app.use(path, route); }); }; // index.js const express = require("express"); const app = express(); const port = 3000; require("./routes")(app); app.listen(port, () => console.log(`App listening at http://localhost:${port}`) );
The other option, as we said earlier, is to export the desired path name in the route file and use this information in the route config file.
To achieve this, we’ll have to export an object with the path and config keys in our route file. In this kind of configuration, we strongly suggest you use the filename path method as a fallback to avoid errors in case you forget to add the path export. This way, we have an extra bonus: a solution that’ll work on both situations.
In our final example, we’ll change the home route path to my_home and leave the about route file as it was.
// /routes/root.js module.exports = { path: "/", config: (router) => { router .get("/", (req, res) => res.send("GET")) .post("/", (req, res) => res.send("POST")); return router; }, }; // /routes/home.js module.exports = { path: "/my_home", config: (router) => { router .get("/", (req, res) => res.send("GET HOME")) .post("/", (req, res) => res.send("POST HOME")); return router; }, }; // /routes/about.js - here we dont export path to use the filename as a path module.exports = (router) => { router .get("/", (req, res) => res.send("GET ABOUT")) .post("/", (req, res) => res.send("POST ABOUT")); return router; }; // routes/index.js const snakeCase = require("lodash/snakeCase"); const express = require("express"); module.exports = (app) => { require("fs") .readdirSync(__dirname) .forEach((file) => { if (file === "index.js") return; const router = express.Router(); const routeModule = require(require("path").join(__dirname, file)); const path = routeModule.path || "/" + (file !== "root.js" ? snakeCase(file.replace(".js", "")) : ""); const route = routeModule.config ? routeModule.config(router) : routeModule(router); app.use(path, route); }); };
And that’s it. Here we have our smarter Express router config. By using this kind of configuration — and solutions like PM2 or Nodemon to watch your app folder and restart automatically on file changes – all you have to do to add a new route is to add a file in the routes folder.
Of course, there’s plenty of space for improvements, like error checking, but this kind of feature I’ll leave to you so you can get used to the code provided and practice your coding skills while trying to achieve whichever feature you think isn’t implemented in my example. To make things easier in your journey, I’ve provided the final code in CodeSandbox. Feel free to fork and work on it.
For more information and to develop web application using Node JS, Hire Node Developer from us, as we give you high quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“. To develop any custom web apps using using Node JS, please visit our technology page.
Content Source:
- medium.com
File upload with Multer using Node.js
File upload is a common operation for any applications. In Node.js, with the Express web framework and the Multer library, adding file upload feature to your app is very easy. In this blog, we are going to learn how to upload files on the server with the help of Multer and Express in Node.js. The goal is to make you comfortable in building apps that can easily handle any file uploads. At the end of this blog, you will be able to integrate the file uploads in your own apps.
What is Multer?
Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files.
What is Multipart Data?
In general, when a “form” is submitted, browsers use “application-xx-www-form-urlencoded” content-type. This type contains only a list of keys and values and therefore are not capable of uploading files. Whereas, when you configure your form to use “multipart/form-data” content-type, browsers will create a “multipart” message where each part will contain a field of the form. A multipart message will consist of text input and file input. This way using multipart/form-data you can upload files.
Multer adds a body object and a file or files object to the request object. The body object contains the values of the text fields of the form, the file or files object contains the files uploaded via the form.
Multer will not process any form which is not multipart (multipart/form-data).
Project Setup
Create a directory for the project and give it any name. We will call it MulterApp.
Now, let’s start by first defining the package.json file to store our app’s configuration. To create one, navigate to the MulterApp directory in terminal, and write the following command:
// In command prompt or terminal npm init
Install the dependencies
Here, the only two dependencies are express and multer. So we will install it one by one via npm(Node Package Manager).
// installing express module npm install express --save
We are now ready to write some code. Create a file with any name of your choice, we will call it app.js. Load the express module using require() method and then set up a basic express server by writing the following code in app.js.
// load express const express = require('express'); const app = express(); app.get(‘/’, (req, res) => { res.send(‘hello world’); }); app.listen(3000, () => { console.log('Started on port 3000'); });
Now run the code by writing the following command in the terminal:
node app.js
After this, open the browser and type http://localhost:3000.
You should see “Hello World” printing to the document window. We have set up the basic server.
Testing Our API Using Postman
Postman is an essential and fantastic tool if you are building rest API. We will use Postman to test our routes. As we are not using any form tag or frontend therefore we will make requests and specify our form data from Postman only. So, make sure that you have Postman installed. Now let’s add multer to our project.
Adding Multer
Before using multer, we have to install it using npm.
// installing multer module npm install multer --save
In this project, we will store the uploaded files in a folder for simplicity. Usually we store the files in the Amazon S3 bucket.
We will now load multer in the app.js file using the require() method. The following code will go in the app.js file.
const multer = require('multer'); const upload = multer({dest:'uploads/'}).single("demo_image");
Here, we have called the multer() method. It accepts an options object, with dest property, which tells Multer where to upload the files. If you omit this object, the files will be kept in memory and never written to disk.
Once this is done, We will now create our post route. We will make a POST request to the URL [localhost:port/image]. For that, we will first have to listen to that endpoint and we will do that by using the post() method.
Here we are making a post request because, in the actual scenario also, It will be a post request only, as the form tag will going to post this data to a specific URL (by specifying method=”POST” and action=”/image” in form tag).
The following code will go in app.js:
app.post("/image", (req, res) => { upload(req, res, (err) => { if(err) { res.status(400).send("Something went wrong!"); } res.send(req.file); }); });
Multer supports uploading a single file as well as multiple files. In this case, we have used multer({..}).single() which is used for uploading a single file. As I have mentioned before that the multer adds a file object to the request. The file object contains metadata related to the file.
Now we will be using Postman to test this endpoint.

pic courtesy : afteracademy.com
Here note that the key name or the field name that you are providing in form data should be the same as the one provided in the multer({..}).single() (here name is demo_image).
Now see your file structure again, notice that uploads folder is created in the location provided in dest option(in our case in the project directory). If you want more controls over the uploads we will use the storage option instead of dest.
DiskStorage
The disk storage engine gives you full control over storing files to disk. We will create a storage object using the diskStorage() method.
The following code will go in app.js:
var storage = multer.diskStorage({ destination: function(req, file, cb) { cb(null, './uploads'); }, filename: function (req, file, cb) { cb(null , file.originalname); } });
Here, there are two properties, destination, and filename. They both are functions.
Destination – It can also be given as a string (e.g. ‘./uploads’). If no destination is given, the operating system’s default directory for temporary files is used. It is mandatory to create a directory when you are using destination as a function. Otherwise, if you are using destination as a string, multer will make sure that the directory is created for you.
Filename – It is used to determine what the file should be named inside the folder. If you don’t provide any filename, each file will be given a random name without any file extension. It is your responsibility to provide a function that should return a complete filename with a file extension. Both these functions take 3 arguments – the request object, the file object and a callback function (here, cb is callback function). The 2 arguments to cb are:
- null – as we don’t want to show any error.
- file.originalname – here, we have used the same name of the file as they were uploaded. You can use any name of your choice.
Now let’s modify the variable a little bit.
// In app.js var upload = multer({ storage: storage }).single("demo_image");
Again test this in Postman. You will find the same output but now check the image in the uploads folder. You will find the same filename as you uploaded, with the proper extension.
Other Options in Upload
-
- limits – You can also put a limit on the size of the file that is being uploaded with the help of using limits.
The following code will go inside the multer().
// inside multer({}), file upto only 1MB can be uploaded const upload = multer({ storage: storage, limits : {fileSize : 1000000} });
- Here, fileSize is in bytes. (1000000 bytes = 1MB)
- fileFilter – Set this to a function to control which files should be uploaded and which should be skipped. The function should look like this:
// this code goes inside the object passed to multer() function fileFilter (req, file, cb) { // The function should call 'cb' with a boolean // to indicate if the file should be accepted // To reject this file pass 'false', like so: cb(null, false); // To accept the file pass 'true', like so: cb(null, true); // You can always pass an error if something goes wrong: cb(new Error('I don\'t have a clue!')); }
For Example, if we only want the user to upload the image file (jpeg, jpg, png, gif).
Then the code will look like this and will go in app.js:
// this code goes inside the object passed to multer() function fileFilter (req, file, cb) { // Allowed ext const filetypes = /jpeg|jpg|png|gif/; // Check ext const extname = filetypes.test(path.extname(file.originalname).toLowerCase()); // Check mime const mimetype = filetypes.test(file.mimetype); if(mimetype && extname){ return cb(null,true); } else { cb('Error: Images Only!'); } }
Uploading Multiple Files
We can upload multiple files as well. In this case, multer gives us another function called .arrays(fieldname[, max_count]) that accepts an array of files, all with the name fieldname. It generates an error if more than max_count files are uploaded. The array of files will be stored in req.files.
The following code will go in app.js
// uploading multiple images together app.post("/images", upload.array("demo_images", 4), (req, res) =>{ try { res.send(req.files); } catch (error) { console.log(error); res.send(400); } });
Go to Postman, enter the specified URL, select multiple files and then press Enter.

pic courtesy : afteracademy.com
For more Information and to build a website using Node JS, Hire Node.js Developer from us, as we give you high quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“. To develop the custom web app using Node.js, please visit our technology page.
Content Source:
- afteracademy.com
AdonisJS: Templating, Authentication and Validators
In our previous post about AdonisJS we had covered introduction, installation, modeling, creating and displaying content, creating and deleting task. Let’s move on remaining part of it with this post.
A bit of templating
Our application is going to grow. In order to reuse some parts of the html, we are going to define a main layout, and include the specific code of each page into it.
Create a “layout_main.edge” file into “resources/views”. This file will include the base of our page, and will be used by each page we create.
<!DOCTYPE html> <html> <title>Task list</title> {{style('style')}} </head> <body> @!section('content') </body> </html>
Now you can refactor tasklist.edge
@layout('layout_main') @section('content') @if(flashMessage('taskHandling')) <span>{{ flashMessage('taskHandling') }}</span> @endif <form action="{{ route('TaskController.create') }}" method="POST"> {{ csrfField() }} <input type="text" name="title" placeholder="title" /> <input type="text" name="description" placeholder="description" /> <button type="submit">Create the task</button> </form> <section> <h1>Tasks</h1> @each(task in tasks) <div class="task"> <h2> @if(task.done) <input type="checkbox" disabled checked /> @else <input type="checkbox" disabled /> @endif {{task.title}} </h2> <form action="/task/delete/{{task.id}}" method="DELETE"> <button type="submit">Delete</button> </form> <p>{{task.description}}</p> </div> @endeach </section> @endsection
Authentication
You have probably already seen that there are some files to manage users in your project (“app/Models/User.js”)
First, let’s add a UserController :
#Choose "For HTTP requests" adonis make:controller UserController
Go to the router (“start/routes.js”) and some routes :
- two routes for the login and register process, displaying the templates with the forms
- two routes for receiving login and register data and handling user creation and login
- One route for the logout process
Route.on('/register').render('register') Route.on('/login').render('login') Route.post('/register', 'UserController.create') Route.post('/login', 'UserController.login') Route.get('/logout', 'UserController.logout')
Then, add the templates :
“resources/views/login.edge”
@layout('layout_main') @section('content') <form action="{{ route('UserController.login') }}" method="POST"> {{ csrfField() }} <input type="text" name="email" placeholder="email" /> <input type="password" name="password" placeholder="" /> <button type="submit">Login</button> </form> @endsection
“resources/views/register.edge”
@layout('layout_main') @section('content') <form action="{{ route('UserController.create') }}" method="POST"> {{ csrfField() }} <input type="text" name="email" placeholder="email" /> <input type="password" name="password" placeholder="" /> <button type="submit">Create new user</button> </form> @endsection
“Controllers/http/UserController.js”
'use strict' const User = use('App/Models/User') class UserController { async create({ request, response, auth }) { const userPayload = request.all(); const user = new User; user.email = userPayload.email; //We will also use the mail as username to simplify things here user.username = userPayload.email; user.password = userPayload.password; await user.save(); await auth.login(user); return response.redirect('/'); } async login({ request, response, auth, session }) { const userPayload = request.all(); try { await auth.attempt(userPayload.email, userPayload.password) } catch (e) { console.log(e); session.flash({ loginError: e }); } return response.redirect('/'); } async logout ({ auth, response }) { await auth.logout(); return response.redirect('/'); } } module.exports = UserController
You can also modify the tasklist template to add the register and login links, and a logout link if the user is logged in.
You can also include the create task form into the loggedIn conditionnal, in order to prevent anonymous users to create tasks.
... @section('content') @loggedIn <a href="logout">Log out</a> @else <a href="login">Log in</a> <a href="register">Register</a> @endloggedIn ...
More features
We now have seen what a basic and naive approach to build a web app can look like. You might have thought about a lot of other features to include in the project. Here is a quick list of other things Adonis can provide to you :
Relations between models
You want the tasks to be owned by users, you can create relations between models with the following syntax :
class User { tasks () { return this.hasMany('App/Model/Task'[, primaryKey, foreignKey]) } }
You can also use hasOne, belongsTo, belongsToMany and manyThrough.
Validators
You can use validators to check is the data flowing into your controllers has the right format, and emit messages (via session.flash for instance) when some errors occurs.
Validators are a 3rd party npm module : https://www.npmjs.com/package/adonis-validator
Using websocket instead of HTTP requests
As you might have seen when creating controllers, you can also generate controllers that are designed to use websockets.
Internationalization
A full guide to make you app multilanguage is available on the Adonis docs as well :
Conclusion
Adonis is a great choice for those who need a full-featured web server framework, and who need to keep control over your implementation.
This framework could be of a great use if you want to kickstart a project, if you want to follow usual guidelines and concepts. It will help you to implement data migrations, keep your code clean, handle data validation…
However, integrating exotic libraries can be painful. Adonis extensions need to be specifically built for this framework. This would be perfect for Adonis and it’s users if the framework would be in a monopoly situation, which is not the case.
Hire Node.js Developer from us, as we give you high quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom web app using Node.js, please visit our technology page.
Content Source:
- blog.sourcerer.io
AdonisJS: A full featured node framework for modern web servers
Node is becoming one of the most elected choices by developers for modern web servers. You can build web servers in various elegant ways, using up-to-date tools such as ExpressJS.
However, a lot of developers had a hard time to stick on a high level framework to build web servers for their applications, sticking with tools that will stay light but will require a lot of configuration and wiring to produce a complete setup for a large project.
we are going to focus on a higher-level framework that comes with batteries included, and that will allow you to implement advanced features easily.
pic courtesy: blog.sourcerer.io
Meet AdonisJS
AdonisJS is a node framework inspired by the well-known Php framework Laravel. It relies on concepts such as dependency injection and service providers to make you design beautiful, reliable and easily testable code.
Get prepared to leave spaghetti code in favor of reusable OO structure.
Installation
First things first, to create a new AdonisJS server, you will need to install Adonis CLI, the command line tool that will help you manage your projects :
npm i -g @adonisjs/cli
This will provide you a “adonis” command to use in your terminal
To create a new adonis application, use the subcommand “new” :
adonis new my-adonis-server
As explained in the log, is uses the default fullstack-app template (adonisjs/adonis-fullstack-app), to create your project in a “my-adonis-server” folder.
You can now go to this folder and start serving your app in development mode :
cd my-adonis-server adonis serve --dev
Your app is now served from your machine, you can now dive into your project !
Keep the server running for the rest of the introduction.
pic courtesy: blog.sourcerer.io
A bit of modeling
Let’s now create one API to manage a resource. In the following chapter, we will create an endpoint to manage tasks.
First, let’s setup the project so it uses sqlite :
adonis install sqlite3
Then create the Task SQL table :
adonis make:migration tasks # select "create table" adonis migration:run
Note that every time you want to edit your database, you will have to create a migration.
Migrations will allow you to save every modification you are doing to your models, and will update data to follow the new formats and rules you are implementing. It is possible to define a "up" method, and a "down" method, depending if you want to switch to go to a newer or older version.
Then, create the model and controller related to this table :
adonis make:model Task adonis make:controller TaskController # select "For HTTP requests"
You now have set up you database, created a table, a model, and a controller. The source code for the model and the controller is present on the app folder.
pic courtesy: blog.sourcerer.io
You might have noticed that as you entered the last commands, the server automatically detected that your project changed, and took care of reloading the new setup.
Now we can add some content to our model. By creating another migration.
adonis make:migration tasks
Now edit the new file under database/migrations
'use strict' const Schema = use('Schema') class TasksSchema extends Schema { up () { this.table('tasks', (table) => { // alter table table.string('title') table.string('description') table.boolean('done') }) } down () { this.table('tasks', (table) => { // reverse alternations }) } } module.exports = TasksSchema
And run this migration
adonis migration:run
Now, you tasks models have a title, description, and done properties.
Creating a page displaying content
Now let’s create a page that displays a list of tasks.
//Route.on('/').render('welcome') Route.get('/', 'TaskController.home')
Then, on your TaskController, add the code handling the “/” route.
'use strict' const Task = use('App/Models/Task') class TaskController { async home({view}) { // Fetch tasks const tasks = await Task.all() return view.render('tasklist', { tasks: tasks.toJSON() }) } } module.exports = TaskController
And add the template of the page in “resources/views/tasklist.edge”
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Task list</title> {{ style('style') }} </head> <body> <section> <h1>Tasks</h1> @each(task in tasks) <div class="task"> <h2> @if(task.done) <input type="checkbox" disabled checked /> @else <input type="checkbox" disabled /> @endif {{task.title}} </h2> <p>{{task.description}}</p> </div> </div> @endeach </section> </body> </html>
In the “public/style.css”, delete all the css rules, to put :
.task { border: 1px solid darkgrey; border-radius: 6px; background: lightgrey; margin: 10px; padding-left: 10px; padding-right: 10px; }
This will display an empty list of tasks on “localhost:3000/” (so basically, nothing at the moment !)
It is currently empty because there is no tasks at the moment on the database. Let’s fix this!
Creating tasks in your database
For the sake of this tutorial, we will create our first tasks on the TaskController method we already defined:
/* ... */ async home({view}) { // Fetch tasks const task1 = new Task task1.title = 'Walk the dog' task1.description = 'Go and walk for half an hour' task1.done = false const task2 = new Task task2.title = 'Feed the cat' task2.description = 'The food is on the fridge' task2.done = false const task3 = new Task task3.title = 'Buy some pizza' task3.description = 'Go at the shop before 7pm' task3.done = true await task1.save() await task2.save() await task3.save() const tasks = await Task.all() return view.render('tasklist', { tasks: tasks.toJSON() }) } /* ... */
Load the tasklist once to insert your tasks in the database, then erase or comment those methods.
You should now see your tasks on the page.
Creating new tasks
Once this working, we would like to add new content via a new task form.
On your task controller, enter the task creation logic :
class TaskController { /* ... */ async create({ request, response, session, auth}) { const taskPayload = request.all() const task = new Task task.title = taskPayload.title task.description = taskPayload.description task.done = false await task.save() session.flash({ message: 'Task created!' }) return response.redirect('back') } }
The task creation form in your tasklist template :
@if(flashMessage('message')) <span>{{ flashMessage('message') }}</span> @endif <form action="{{ route('TaskController.create') }}" method="POST"> <input type="text" name="title" placeholder="title" /> <input type="text" name="description" placeholder="description" /> <button type="submit">Create task</button> </form> ...
And the post route in “start/routes.js”
Route.post('/task/create', 'TaskController.create')
Now you can add tasks from the form displayed in your task list.
Deleting Tasks
To delete tasks, the implementation is pretty much the same as the one we did to create tasks :
- Add a delete method in the controller
- Adapt the template
- Create the DELETE route
TaskController :
/* ... */ class TaskController { /* ... */ async delete({ request, response, session, params}) { const task = await Task.find(params.id) await task.delete() session.flash({ taskHandling: 'Task deleted!'}) return response.redirect('back') } }
“resources/views/tasklist.edge”
... <section> <h1>Tasks</h1> @each(task in tasks) <div class="task"> <h2> @if(task.done) <input type="checkbox" disabled checked /> @else <input type="checkbox" disabled /> @endif {{task.title}} </h2> <a href="/task/delete/{{task.id}}">Delete</a> <p>{{task.description}}</p> </div> </div> @endeach </section> ...
“start/routes.js”
Route.get('/task/delete/:id', 'TaskController.delete')
In this blog we have covered the basics of Adonis JS. If you really enjoyed reading it, please checkout our next blog in series to learn more about ‘Templating’, ‘Authentication’ and many more Adonis JS features.
Hire Node.js Developer from us, as we give you high quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom web app using Node.js, please visit our technology page.
Content Source:
- blog.sourcerer.io
Top 3 most popular Node.js frameworks for 2018
Enhancing JavaScript capability for server-side scripting, Node.js Framework development has come to the forefront among the programming languages in 2018. Node.js brought a noteworthy move, of running JavaScript outside the browser which is largely acknowledged by the JavaScript developers. Being technology contributors we are already aware of the Node.js backend development and web application development capability.
Due to its distinguished features, Node.js is high on the demand of backend developer community and technology giants. Major features consist of the single-threaded event loop and asynchronous and non-blocking input/output processing. Using this primary features and approaches of Node.js, many performance-driven frameworks are being innovated.
These Node.js frameworks can be leveraged to speed up development cycles and gear up the power of Node.js development, In addition, these frameworks also let you to craft real-time end to end web applications without any other third party app server, web server, technology or tool.
Here, we are describing 3 top Node.js frameworks that have extended the core functionality of Node.js with latest features and will be emerging rapidly in 2018.
Express.js
Express.js is one of the most important web application development frameworks for Node.js and has brought Node.js to next level. It is a flexible and minimalist Node.js web framework for developing robust web applications and mobile app programming interfaces.
Express.js is incorporated applicable features, like simplified multiple routing, database integration, template engines and so on. Moreover, Expert Node.js Developers can also write extension or plugins or packages for express. Well-known websites and apps such as Geekli.st, MySpace, Yummly, Klout, and Segment.io are built in Express.js.
Express gives the flexibility to use any template engine conforming to the signatures, any user authentication scheme, and any third party database. It helps you to define the project directory structure the way you want.
Meteor
Meteor is powerful open source MVC Node.js framework for developing web and mobile applications. The framework lets you build real-time applications for both client and server. Meteor mainly supports Linux, Windows, and macOS.
You can create an application with fewer JavaScript code using reactive programming model offered by Meteor. Some of the popular applications like Blonk a Job search application and Respondly a team collaboration app are built using Meteor.
Meteor has the DDP protocol which lets you connect to anything in the backend, like enterprise data warehouse and a simple database, to the IoT sensors. Meteor can quickly integrate with MongoDB.
Metro is having good demand in the market as per its 28K+ stars on GitHub and huge supportive community. Everything in meteor works seamless and out of the box.
Socket.io
It is the best server and Node js web framework for creating real-time web applications, allowing event-driven interaction between a node.js server and a browser. It performs as a server-side library for node.js and as a client-side library in the browser.
The prime features of Socket.io comprise binary streaming, asynchronous input/ output (I/O) processing, and instant messaging and more. It allows real-time concurrency for the need for document collaboration.
The framework is compatible with every operating system, device, and browser. Top technology companies including Microsoft, Trello, Yammer, and Zendesk have been using this framework.
Hire Node.js Developer having expert level in implementation working with Express JS, Meteor and/or Socket.io server technology. To develop the custom web app using any of above listed Node.js frameworks, please inquire us via E-mail – hello@hkinfosoft.com or Skype: “hkinfosoft“.
Content Source:
- designwebkit.com