DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

Ammar Javed
Ammar Javed

Posted on

Create APIs with Dart Frog Backend Server For Flutter / Dart

A backend server called Dart Frog is developed in Dart and intended to be scalable, quick, and reliable. It is available under a free and open-source license.
In this article, we will learn how to use dart frog to create APIs, and before knowing how to create APIs using dart frog flutter, we should also know about what is dart frog flutter.

Contents:

  • What is Dart Frog in Flutter
  • What is Dart Programming Language
  • What is Flutter
  • What is MySQL
  • What is Middleware in Dart Frog
  • What is Dependency Injection in Dart Frog
  • What is Custom Entry Point in Dart Frog
  • How to Create APIs with Dart Frog Backend Server
  • FAQS on Create APIs with Dart Frog Backend Server For Flutter / Dart
  • Source Files of Create APIs with Dart Frog Backend Server For Flutter / Dart
  • Conclusion of Dart Frog Flutter Backend Server APIs

What is Dart Frog in Flutter

A backend server called Dart Frog can be used to create client-server-based apps. The flutter developers can use the Dart Frog backend server to create APIs. Applications of any scale may be developed, tested, deployed, and run in an intuitive environment using Dart Frog.

What is Dart Programming Langauge

Dart is a general-purpose programming language. Dart is a client language enabling rapid app development on any platform. It was created by Google and afterward accepted by ECMA as a standard. Dart is developed for a specialized technical envelope for client development that focuses both on development and high-quality manufacturing experience across a wide range of compiling platforms. Dart provides several fundamental developer activities such as formatting, analysis, and code testing. Dart is a new language for both server and browser development.

Related: What is Dart and What is Dart used for?

What is Flutter

A flutter is a tool that allows building native cross-platform (Android, iOS, Linux, Web, Mac, Windows, Google Fuchsia) apps with one programming language and codebase.
We use one programming language so that we donโ€™t have to learn different programming languages such as one for iOS, one for Android, and one for the Web, instead, we have one programming language. So we work on one project, we write our code once and we still get different apps as a result, and thatโ€™s the cool thing about Flutter.

Related: What is Flutter?

What is MySQL

SQL is used to query MySQL, a relational database management system (RDBMS) that stores data in tables. It has been released under the GPL since its inception and can be installed on a variety of operating systems. The most widely used open-source database in the world is still MySQL, as it has been for many years.

What is Middleware in Dart Frog

Middleware allows us to execute a code before or after the request. So we can modify the request or responses as per our requirements.

What is Dependency Injection in Dart Frog

Middleware helps us to inject dependency on the current request with the help of the provider which is a type of middleware that create and provide an instance of Type T in the current request context.

What is Custom Entry Point in Dart Frog

Custom Entry Point in Dart Frog can be used to execute code before running the server.

How to Create APIs with Dart Frog Backend Server

  1. How to Install dart_forg_cli Open the terminal and run the below command

dart pub global activate dart_frog_cli

  1. How to create a new Dart project Open the terminal and run the below command

dart_frog create name_of_project such as dart_frog create dart_frog_apis_ammarjavedofficial

  1. Open the Dart project
    Iโ€™ll open the project in VSCode because Iโ€™ll be using VSCode throughout the article on How to create APIs with dart frog a backend server.

  2. How to start the Dart Frog backend server
    In the VSCode open the terminal and run the below command

dart_frog dev

or we can run the server on the port of our choice using the below command

dart_frog dev --port 7878

  1. Connecting with Database Iโ€™ll use MySQL database for storing the data in the database. Thatโ€™s why Iโ€™ll use XAMPP to run the Apache server and MySQL database. In the VSCode terminal execute the below command

dart pub add mysql_client

The mysql_client package will help us to connect with the MySQL database.

In the project folder, create a new folder lib. In the lib folder create a folder database. In the database folder, create a new file mysql_client.dart.
Open the mysql_client.dart file and paste the below code to have a connection with the database.

import 'package:mysql_client/mysql_client.dart';
///
class MySQLClientConnection {
///
factory MySQLClientConnection() {
return _inst;
}
MySQLClientConnection._internal() {
_connectDatabase();
}
static final MySQLClientConnection _inst = MySQLClientConnection._internal();
MySQLConnection? _connection;
///
Future _connectDatabase() async {
_connection = await MySQLConnection.createConnection(
host: 'localhost',
port: 3306,
userName: 'root',
password: '1234',
databaseName: 'crud',
secure: false,
);
await _connection?.connect();
}
///
Future runQuery(
String query, {
Map? params,
bool iterable = false,
}) async {
if (_connection == null || _connection?.connected == false) {
await _connectDatabase();
}
if (_connection?.connected == false) {
throw Exception('Could not connect to the database');
}
return _connection!.execute(query, params, iterable);
}
///
bool? get checkDatabaseConnection {
return _connection?.connected;
}
}

The connectDatabase method is used to connect with the MySQL Database and the runQuery method is used to execute the MySQL query and for checking database connectivity.
The getter checkDatabaseConnection method is used to check if the database is running or not.

  1. Checking Database Connectivity with the API EndPoint In the project folder, create a file main.dart and in the main.dart file paste the below code for the database initialization.

import 'dart:io';
import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/database/mysql_client.dart';
final mySQLClientConnection = MySQLClientConnection();
Future run(Handler handler, InternetAddress ip, int port) {
return serve(handler.use(databaseHandler()), ip, port, poweredByHeader: 'Dart Frog Apis - AmmarJavedOfficial',);
}
Middleware databaseHandler() {
return (handler) {
return handler.use(
provider(
(context) => mySQLClientConnection,
),
);
};
}

Now open the routes folder and in the index.dart file paste the below code.

import 'package:dart_frog/dart_frog.dart';
import '../main.dart';
Future onRequest(RequestContext context) async {
if (context.request.method.name == 'get') {
try {
return Response.json(
body: mySQLClientConnection.checkDatabaseConnection == true
? 'Connection Successfully'
: 'Connection Unsuccessful',
);
} catch (error) {
return Response(body: error.toString());
}
} else {
return Response.json(
body: {
'error':
'${context.request.method.name.toUpperCase()} Method Not Supported'
},
);
}
}

Run the http://localhost:7878 API endpoint in the postman to check whether the database connection is successful or not.

  1. Creating a Model folder Inside the lib folder create a new folder models and inside the models folder create a new file users_model.dart and paste the below code.

///
class UsersModel {
///
factory UsersModel.fromJson(Map json) {
return UsersModel(
userId: json['userId'] as String,
userName: json['userName'] as String,
userPassword: json['userPassword'] as String,
);
}
///
factory UsersModel.databseRow(Map json) {
return UsersModel(
userId: json['userId'],
userName: json['userName'],
userPassword: json['userPassword'],
);
}
///
Map toJson() {
return {
'userId': userId,
'userName': userName,
'userPassword': userPassword,
};
}
///
UsersModel({
this.userId,
this.userName,
this.userPassword,
});
///id
final String? userId;
///userName
final String? userName;
///password
final String? userPassword;
}

We will be using the methods inside the UsersModel class in order to handle the JSON data.

  1. Creating a Controller folder Inside the lib folder create new folder controllers and inside the controllers folder create a new file users_controller.dart and paste the below code.

import 'package:dart_frog_apis_ammarjavedofficial/database/mysql_client.dart';
import 'package:dart_frog_apis_ammarjavedofficial/models/users_model.dart';
///
class UsersController {
///
UsersController(this._mySQLClientConnection);
final MySQLClientConnection _mySQLClientConnection;
///
Future> postUserCreate({
required String? userName,
required String? userPassword,
}) async {
await _mySQLClientConnection.runQuery(
"INSERT INTO
users_table(userName,userPassword) VALUES ('$userName','$userPassword')");
return {
'success': 'User Created',
};
}
///
Future> getAllUsersList() async {
final items = [];
final result = await _mySQLClientConnection.runQuery(
'SELECT * from users_table',);
for (final row in result.rows) {
items.add(UsersModel.databseRow(row.assoc()));
}
return items;
}
///
Future> getUserDetailsById(
{
String? userId
}
) async {
final result = await _mySQLClientConnection
.runQuery("SELECT * FROM
users_tableWHERE userId = $userId");
if (result.numOfRows != 0) {
return result.rows.first.assoc();
} else {
return {'error': "User Don't Exists"};
}
}
///
Future> patchUserUpdate({
String? userId,
required String? userName,
required String? userPassword,
}) async {
final result = await _mySQLClientConnection.runQuery(
"UPDATE
users_tableSETuserName='$userName',userPassword='$userPassword' WHERE userId = $userId");
if (result.affectedRows != BigInt.from(0)) {
return {'success': 'User Updated'};
} else {
return {'error': "User Don't Exists"};
}
}
///
Future> deleteUserDelete(
{
String? userId
}
) async {
final result = await _mySQLClientConnection
.runQuery('DELETE FROM
users_tableWHERE userId = $userId;');
if (result.affectedRows != BigInt.from(0)) {
return {
'success': 'User Deleted',
};
} else {
return {'error': "User Don't Exists"};
}
}
///
Future> deleteAllUsers(
) async {
final result = await _mySQLClientConnection
.runQuery("DELETE FROM
users_table");
if (result.affectedRows != BigInt.from(0)) {
return {
'success': 'Users Deleted',
};
} else {
return {'error': "Users Don't Exists"};
}
}
}

We will be using the methods inside the UsersController class to execute the SQL queries in order to get the list of all users, and detail of a specific user, update a user, create a new user, and delete users.

  1. Create a User using the API endPoint In the routes folder, create a new folder users. In the users folder create a folder PostUserCreate and in the PostUserCreate folder create a file _middleware.dart and index.dart. In the _middleware.dart file paste the below code for dependency Injection.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
import '../../../main.dart';
Handler middleware(Handler handler) {
return handler.use(requestLogger()).use(injectionHandler());
}
Middleware injectionHandler() {
return (handler) {
return handler.use(
provider(
(context) => UsersController(mySQLClientConnection),
),
);
};
}

In the index.dart file paste the below code in order to have access to the UsersController class object and to create a new user using the API endpoint.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
Future onRequest(RequestContext context,) async {
final usersMiddleware = context.read();
if (context.request.method.name == 'post') {
final userName = context.request.uri.queryParameters['userName'];
final userPassword = context.request.uri.queryParameters['userPassword'];
if(userName != null && userPassword != null)
{
try {
final users = await usersMiddleware.postUserCreate(
userName: userName,
userPassword: userPassword,
);
return Response.json(body: users);
} catch (error) {
return Response(body: error.toString());
}
} else {
return Response.json(body: {'error' : 'All Parameters Are Required'});
}
} else {
return Response.json(
body: {'error': '${context.request.method.name.toUpperCase()} Method Not Supported'},
);
}
}

Now in the Postman run the http://localhost:7878/users/PostUserCreate?userName=AmmarJavedOfficial&userPassword=123456789 API endpoint to create a new user.

  1. Get a List of Users using the API endPoint In the users folder, create a folder GetAllUsers and in the GetAllUsers folder create a file _middleware.dart and index.dart. In the _middleware.dart file paste the below code for returning the instance of UsersController class.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
import '../../../main.dart';
Handler middleware(Handler handler) {
return handler.use(requestLogger()).use(injectionHandler());
}
Middleware injectionHandler() {
return (handler) {
return handler.use(
provider(
(context) => UsersController(mySQLClientConnection),
),
);
};
}

In the index.dart file paste the below code in order to have access to the UsersController class instance and to fetch all users from the database.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
Future onRequest(RequestContext context) async {
final usersMiddleware = context.read();
if (context.request.method.name == 'get') {
try {
final users = await usersMiddleware.getAllUsersList();
if (users.isEmpty) {
return Response.json(
body: {
'error': 'No User Exists',
},
);
} else {
return Response.json(
body: users,
);
}
} catch (error) {
return Response(body: error.toString());
}
} else {
return Response.json(
body: {'error': '${context.request.method.name.toUpperCase()} Method Not Supported'},
);
}
}

Now in the Postman run the http://localhost:7878/users/GetAllUsers API endpoint to get the list of all users.

  1. Get User Details using the API endPoint In the users folder, create a folder GetUserDetails and in the GetUserDetails folder create a file _middleware.dart and index.dart. In the _middleware.dart file paste the below code for returning the instance of UsersController class.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
import '../../../main.dart';
Handler middleware(Handler handler) {
return handler.use(requestLogger()).use(injectionHandler());
}
Middleware injectionHandler() {
return (handler) {
return handler.use(
provider(
(context) => UsersController(mySQLClientConnection),
),
);
};
}

In the index.dart file paste the below code in order to have access to the UsersController class instance and to fetch all users from the database.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
Future onRequest(RequestContext context) async {
final usersMiddleware = context.read();
if (context.request.method.name == 'get') {
final userId = context.request.uri.queryParameters['userId'];
if (userId!.isNotEmpty) {
try {
final users = await usersMiddleware.getUserDetailsById(
userId: userId,
);
return Response.json(
body: users,
);
} catch (error) {
return Response(body: error.toString());
}
} else {
return Response.json(
body: {
'error': 'User Id is Required',
},
);
}
} else {
return Response.json(
body: {'error': '${context.request.method.name.toUpperCase()} Method Not Supported'},
);
}
}

Now in the Postman run the http://localhost:7878/users/GetUserDetails?userId=1 API endpoint to get the details of a user.

  1. Update User Details using the API endPoint In the users folder, create a folder PatchUserUpdate and in the PatchUserUpdate folder create a file _middleware.dart and index.dart. In the _middleware.dart file paste the below code for dependency injection using the provider.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
import '../../../main.dart';
Handler middleware(Handler handler) {
return handler.use(requestLogger()).use(injectionHandler());
}
Middleware injectionHandler() {
return (handler) {
return handler.use(
provider(
(context) => UsersController(mySQLClientConnection),
),
);
};
}

In the index.dart file paste the below code in order to have access to the UsersController class instance and to update the details of a specific user by id.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
Future onRequest(RequestContext context,) async {
final usersMiddleware = context.read();
if (context.request.method.name == 'patch') {
final userId = context.request.uri.queryParameters['userId'];
final userName = context.request.uri.queryParameters['userName'];
final userPassword = context.request.uri.queryParameters['userPassword'];
if(userId != null)
{
try {
final users = await usersMiddleware.patchUserUpdate(
userId: userId,
userName: userName,
userPassword: userPassword,
);
return Response.json(body: users);
} catch (error) {
return Response(body: error.toString());
}
} else {
return Response.json(body: {'error' : 'User Id is Required'});
}
} else {
return Response.json(
body: {'error': '${context.request.method.name.toUpperCase()} Method Not Supported'},
);
}
}

Now in the Postman run the http://localhost:7878/users/PatchUserUpdate?userName=AJOfficial&userPassword=123456 API endpoint to update a user.

  1. Delete a Specific User using the API endPoint In the users folder, create a folder DeleteUserDelete and in the DeleteUserDelete folder create a file _middleware.dart and index.dart. In the _middleware.dart file paste the below code for dependency injection using the provider.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
import '../../../main.dart';
Handler middleware(Handler handler) {
return handler.use(requestLogger()).use(injectionHandler());
}
Middleware injectionHandler() {
return (handler) {
return handler.use(
provider(
(context) => UsersController(mySQLClientConnection),
),
);
};
}

In the index.dart file paste the below code in order to have access to the UsersController class instance and to delete a specific user by id.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
Future onRequest(RequestContext context, String userId) async {
final usersMiddleware = context.read();
if (context.request.method.name == 'delete') {
try {
final users = await usersMiddleware.deleteUserDelete(
userId: userId,
);
return Response.json(body: users);
} catch (error) {
return Response(body: error.toString());
}
} else {
return Response.json(
body: {'error': '${context.request.method.name.toUpperCase()} Method Not Supported'},
);
}
}

Now in the Postman run the http://localhost:7878/users/DeleteUserDelete/1 API endpoint to delete a user.

  1. Deleting All Users using the API endPoint In the users folder, create a folder DeleteAllUsers and in the DeleteAllUsers folder create a file _middleware.dart and index.dart. In the _middleware.dart file paste the below code for dependency injection using the provider.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
import '../../../main.dart';
Handler middleware(Handler handler) {
return handler.use(requestLogger()).use(injectionHandler());
}
Middleware injectionHandler() {
return (handler) {
return handler.use(
provider(
(context) => UsersController(mySQLClientConnection),
),
);
};
}

In the index.dart file paste the below code in order to have access to the UsersController class instance and to delete all users.

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog_apis_ammarjavedofficial/controllers/users_controller.dart';
Future onRequest(RequestContext context) async {
final usersMiddleware = context.read();
if (context.request.method.name == 'delete') {
try {
final users = await usersMiddleware.deleteAllUsers();
return Response.json(body: users);
} catch (error) {
return Response(body: error.toString());
}
} else {
return Response.json(
body: {'error': '${context.request.method.name.toUpperCase()} Method Not Supported'},
);
}
}

Now in the Postman run the http://localhost:7878/users/DeleteAllUsers API endpoint to delete all users.

FAQS on Create APIs with Dart Frog Backend Server For Flutter / Dart

  1. What are the Features of Dart Frog Backend Server?
  • Hot Reload
  • Dart Dev Tools
  • Static File Support
  • File System Routing
  • Index Routes
  • Nested Routes
  • Dynamic Routes
  • Middleware
  • Dependency Injection

Source Files of Create APIs with Dart Frog Backend Server For Flutter / Dart

GitHub
https://github.com/ammarjavedofficial/dart_frog_apis_ammarjavedofficial

Database File
https://drive.google.com/file/d/17kbftHpF3DO7ttLP9N6_GEXmMBsr8PCo/view?usp=sharing

Postman JSON File
https://drive.google.com/file/d/1F5rlSBWGFUzVyMWeRmekX76jiSTOUiG2/view?usp=sharing

Conclusion of Dart Frog Flutter Backend Server APIs

In this article, we get to know how to create APIs using dart frog.

Top comments (0)

An Animated Guide to Node.js Event Lop

Node.js doesnโ€™t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.