Integrate Flutter with Node.js: to create powerful, full-stack mobile applications
- Basic concepts of node.js
- How to integrate node.js with flutter
What is Node.js?
Node.js is an open-source, server-side JavaScript runtime environment that allows you to run JavaScript code on the server. It uses the V8 JavaScript engine, which is the same engine that powers Google Chrome. Node.js provides an event-driven, non-blocking I/O (input/output) model that makes it efficient and scalable for building web applications.
Here are some key points about Node.js:
- JavaScript on the Server: Node.js enables developers to use JavaScript not just on the client-side (in web browsers) but also on the server-side. This unifies the development language and allows developers to use the same programming language for both client and server code.
- Asynchronous and Non-Blocking: Node.js uses an event-driven, non-blocking I/O model, which means that it can handle many concurrent connections efficiently without blocking the execution of other tasks. This makes it well-suited for building real-time applications, chat applications, streaming services, and other applications that require handling multiple simultaneous connections.
- Single-Threaded Event Loop: Node.js operates on a single-threaded event loop, which allows it to handle many concurrent connections while efficiently utilizing system resources. It achieves this by using callbacks and event-driven programming, where functions are executed in response to specific events.
- Rich Ecosystem and Package Manager: Node.js has a vast ecosystem of open-source libraries and frameworks available through its package manager called npm (Node Package Manager). Developers can easily integrate these modules into their applications to add functionalities, such as database connectivity, web frameworks, authentication, and much more.
- Scalability and Performance: Node.js is designed to be highly scalable and performant. Its non-blocking I/O model allows it to handle a large number of concurrent connections efficiently, making it suitable for building applications that need to handle high traffic and real-time data.
- Cross-Platform: Node.js runs on various operating systems, including Windows, macOS, and Linux, making it a versatile choice for building applications that can run across different platforms.
Node.js is widely used in web development for building server-side applications, APIs, microservices, real-time applications, and even desktop applications. Its popularity and vibrant ecosystem have made it a popular choice among developers for building modern, scalable, and efficient web applications.
What is NPM?
NPM (Node Package Manager) is a package manager for Node.js, which is a software registry and command-line tool used for managing and sharing reusable JavaScript code modules. It is the default package manager for Node.js and is widely used in the JavaScript community.
Here are some key points about NPM:
- Package Management: NPM allows developers to easily install, manage, and update packages or modules for their Node.js projects. These packages can contain various functionalities, libraries, frameworks, utilities, and other code resources that developers can use to enhance their applications.
- Package Registry: NPM maintains a vast public registry, npmjs.com, where developers can publish and share their packages with others. The registry hosts millions of packages, making it a rich source of reusable code that developers can leverage in their projects.
- Command-Line Interface (CLI): NPM provides a command-line interface that developers can use to interact with the package manager. They can use commands such as npm install, npm update, npm uninstall, and many more to manage their project dependencies, install packages, and perform various package-related operations.
- Dependency Management: NPM enables developers to define and manage project dependencies in a straightforward manner. By specifying the required packages and their versions in a configuration file called package.json, NPM can automatically fetch and install the necessary dependencies for a project.
- Scripts and Lifecycle Hooks: NPM allows developers to define custom scripts in the package.json file, which can be executed using the npm run command. These scripts can automate various development tasks, such as building the project, running tests, starting the server, and more. NPM also provides lifecycle hooks, such as pre-install, post-install, pre-publish, etc., that allow developers to execute custom code at specific points during the package installation or publishing process.
- Private Packages and Organizations: In addition to the public registry, NPM offers features for managing private packages and creating organizations. Developers can publish private packages to share code within their teams or organizations, ensuring that sensitive code remains accessible only to authorized individuals.
NPM has become an integral part of the JavaScript ecosystem and is widely used for managing dependencies and leveraging existing code resources. It simplifies package management, fosters code reuse, and provides a robust infrastructure for sharing and collaborating on JavaScript projects.
How To Create a Web Server in Node.js with the HTTP Module
Node as a web server using HTTP
Let’s look at an example of how to create and run our first Node js application.
Our application is going to create a simple server module which will listen on port no 7000. If a request is made through the browser on this port no, then server application will send a ‘Hello World’ response to the client.
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Now, run your web server using node app.js
. Visit http://localhost:3000
and you will see a message saying "Hello World".
Refer to the Introduction to Node.js for a more comprehensive guide to getting started with Node.js
Creating an API for the Flutter App
Now that we have a basic Node.js server set up, we can create an API that the Flutter app can use to communicate with the server. For this example, we’ll create a simple API that returns a list of books.
Add the following code to your server.js
file:
const books = [
{id: 1, title: 'Alice in Wonderland', author: 'Lewis Carrol'},
{id: 2, title: 'Around the World in eighty days', author: 'Jules Verne'},
{id: 3, title: 'Utopia', author: 'Sir Thomas Moor'},
]
app.get('/api/books', (req, res) => {
res.json(books)
})
This code creates an array of book objects and sets up an API endpoint at /api/books
that returns the array as JSON.
To test the API, run the server using the ‘node server.js’ command and visit http://localhost:3000/api/books in your web browser. You should see the list of books in JSON format.
Integrating the API with Flutter
With the Node.js server and API set up, we can now integrate it with a Flutter mobile application. To do this, we’ll use the http
package to make HTTP requests to the API.
First, we will create a model for the book data.
class Book {
final int id;
final String title;
final String author;
Book({required this.id, required this.title, required this.author});
factory Book.fromJson(Map<String, dynamic> json) {
return Book(
id: json['id'],
title: json['title'],
author: json['author'],
);
}
}
In this example, we define a Book class that represents a book with an id, title, and author.
Then add the following code to the lib/main.dart
file:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(BookApp());
class BookApp extends StatelessWidget {
@override
Widget build(BuildContext context){
return MaterialApp(
home: BooksScreen(),
);
}
}
class BooksScreen extends StatefulWidget {
@override
_BooksScreenState createState() => _BooksScreenState();
}
class _BooksScreenState extends State<BooksScreen> {
List<Book> _books = [];
@override
void initState() {
super.initState();
_fetchBooks();
}
Future<void> _fetchBooks() async {
final response = await http.get(Uri.parse('http://localhost:3000/api/books'));
if (response.statusCode == 200) {
final List<dynamic> json = jsonDecode(response.body);
setState(() {
_books = json.map((item) => Book.fromJson(item)).toList();
});
} else {
throw Exception('Failed to load books');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Books'),
),
body: ListView.builder(
itemCount: _books.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(_books[index].title),
subtitle: Text(_books[index].author),
);
},
),
);
}
}
In the above code, we define a BooksScreen widget that fetches the list of books from the API endpoint /api/books and displays them in a ListView.builder. The Book.fromJson method is used to convert each JSON object from the API response to a Book object.
To display the list of books, we use the ListView.builder widget that takes an ‘itemCount’ and an ‘itemBuilder’ callback. The itemCount is set to the length of the _books list, and the itemBuilder callback is called for each item in the list. In the itemBuilder callback, we return a ListTile widget that displays the book’s title and author.
To run this Flutter UI, we need to start the Node.js server that serves the API, and then run the Flutter app on an emulator or physical device. We can do that by running the following commands in the terminal:
$ node server.js
$ flutter run