0% found this document useful (0 votes)
109 views

09 Interacting With REST API

1. The document describes a sample Flutter application called CourseApp that interacts with a REST API using the Bloc architecture. 2. It demonstrates making CRUD requests to perform operations like creating, reading, updating, and deleting course data from a remote REST API using the http package. 3. The application follows a layered architecture with separate directories for presentation, business logic, and data layers, and makes use of additional packages like flutter_bloc, http, and equatable.

Uploaded by

DANIEL ABERA
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
109 views

09 Interacting With REST API

1. The document describes a sample Flutter application called CourseApp that interacts with a REST API using the Bloc architecture. 2. It demonstrates making CRUD requests to perform operations like creating, reading, updating, and deleting course data from a remote REST API using the http package. 3. The application follows a layered architecture with separate directories for presentation, business logic, and data layers, and makes use of additional packages like flutter_bloc, http, and equatable.

Uploaded by

DANIEL ABERA
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 59

Interacting with RESTful API

Flutter, http and Bloc


Learning Outcomes
After completing this session you should be able to

Interact with REST API using http package and bloc

Explore the Layered Architecture of Bloc

Use Flutter forms

Validate Flutter forms

Organize code files based on application feature and layered architecture

Organize imports using barrel files


Introduction
The following slides explain a sample CRUD application named CourseApp
which

Interacts with a REST API

Uses Bloc’s Architecture

The full code of the application is linked below

https://github.com/betsegawlemma/course_flutter_app/tree/main
/lib
Making Network Request
Adding the http package dependency in your pubspec.yaml file

Dependencies:

flutter:
sdk: flutter
http: ^0.12.2
Making Network Request
Importing the http package

import 'package:http/http.dart' as http;


Making Network Request
Adding the Internet permission in your AndroidManifest.xml file
<!-- Required to fetch data from the internet. -->
<uses-permission android:name="android.permission.INTERNET" />
Making Network Request
We will use the model shown in the next slide to demonstrate how to perform
CRUD operation on a remote REST API
The CRUD methods shown in subsequent slides are used in the
CourseDataProvider class later
The base URL of the rest API is
baseUrl = http://localhost
class Course {
String id;
String title;
String description;
int ects;

Course({this.id, this.title, this.description, this.ects});

factory Course.fromJson(Map<String, dynamic> json) {


return Course(
id: json['id'],
title: json['title'],
description: json['description'],
ects: json['ects'],
);
}
}
CRUD: Create Data
Sending POST request to REST API

Use the post method provided by the http package


Future<Course> createCourse (Course course) async {
final response = await http.post(
Uri.https('localhost:3000 ', '/courses' ),
headers: <String, String>{
'Content-Type' : 'application/json; charset=UTF-8' ,
},
body: jsonEncode (<String, String>{
'title': course.title,
'description' : course.description ,
'ects': course.ects ,
}),
);
if (response.statusCode == 200) {
return Course.fromJson(jsonDecode (response.body));
} else {
throw Exception('Failed to load course' );
}
}
CRUD: Read Data
Sending GET request to REST API

Use the get method provided by the http package


Future<Course> getCourse(String id) async {
final response = await http.get('$baseUrl/courses/$id');

if (response.statusCode == 200) {
return Course.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load course');
}
}
CRUD: Update Data
Sending UPDATE request to REST API

Use the put method provided by the http package


Future<void> updateCourse(Course course) async {
final http.Response response = await http.put(
'$baseUrl/courses/${course.id}',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, dynamic>{
'id': course.id,
'title': course.title,
'description' : course.description ,
'ects': course.ects ,
}),
);
if (response.statusCode != 204) {
throw Exception('Failed to load course');
}
}
CRUD: Delete Data
Sending DELETE request to REST API

Use the delete method provided by the http package


Future<void> deleteCourse(String id) async {
final http.Response response = await http.delete(
'$baseUrl/courses/$id',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);

if (response.statusCode != 204) {
throw Exception('Failed to delete course.');
}
}
Sample CourseApp
Simple Flutter CRUD Application to Manage Course Info

Add New Course

Update Course Info

Delete Course Info

List All courses


CourseApp: The REST API
POST Request

curl -d '{"title": "AMP", "code":"SITE0132",


"description": "lorem ipsum", "ects": 7}' -H
'Content-Type: application/json' -X POST
http://localhost:3000/courses/

Result (returns 200 OK on success)

{"id":"60266dfa3eb8d71118fb4c22","title":"AMP","code":"SI
TE0132","description":"lorem ipsum","ects":7}
The REST API
GET Request

curl -X GET http://localhost:3000/courses

Result (returns 200 OK on success)

[{"id":"60266dfa3eb8d71118fb4c22","title":"AMP","code":"S
ITE0132","description":"lorem
ipsum","ects":7},{"id":"60266eaa3eb8d71118fb4c23","title"
:"SEII","code":"SITE0232","description":"Lorem
Ipsum","ects":5}]
The REST API
PUT Request

curl -d '{"title": "Software Engineering


II","code":"SITE0232", "description": "lorem ipsum",
"ects": 7}' -H 'Content-Type: application/json' -X PUT
http://localhost:3000/courses/60266eaa3eb8d71118fb4c23

Result (returns 204 No Content on success)

No content
The REST API
DELETE Request

curl -X DELETE
http://localhost:3000/courses/60266eaa3eb8d71118fb4c23

Result (returns 204 No Content on success)

No content
Sample CRUD Application
List of Courses Screen
Sample CRUD Application
Add New Course Screen
Sample CRUD Application
Course Detail Screen

Notice the Edit and Delete icons at the right side of


the AppBar
Sample CRUD Application
Edit Course Screen

This is the same screen as Add Course screen

The difference is that now the form is populated with


the tobe updated course information
CourseApp Architecture
Presentation

Business Logic

Data

Repository

Data Provider
Code Structure
Create separate directory for each feature inside
the lib directory

Inside the feature directory have separate directory


for each layer
Libraries
The following additional libraries are used

flutter_bloc

http

equatable
CourseApp: Screens
course_add_update.dart

Contains widgets for Adding and Updating


course information
https://github.com/betsegawlemma/course_flu
tter_app/blob/main/lib/course/screens/cours
e_add_update.dart
CourseApp: Screens
course_add_update.dart

Contains widgets for Adding and Updating


course information
https://github.com/betsegawlemma/course_flu
tter_app/blob/main/lib/course/screens/cours
e_add_update.dart
CourseApp: Screens
course_add_update.dart

Contains widgets for Adding and Updating


course information
https://github.com/betsegawlemma/course_flu
tter_app/blob/main/lib/course/screens/cours
e_add_update.dart
CourseApp: Screens
course_detail.dart

Contains widgets to display course details


https://github.com/betsegawlemma/course_flu
tter_app/blob/main/lib/course/screens/cours
e_detail.dart
CourseApp: Screens
course_detail.dart

Contains widgets to display course details


https://github.com/betsegawlemma/course_flu
tter_app/blob/main/lib/course/screens/cours
e_detail.dart
CourseApp: Screens
course_list.dart

Contains widgets to list course details


https://github.com/betsegawlemma/course_f
lutter_app/blob/main/lib/course/screens/c
ourse_list.dart
CourseApp: Screens
course_list.dart

Contains widgets to list course details


https://github.com/betsegawlemma/course_f
lutter_app/blob/main/lib/course/screens/c
ourse_list.dart
CourseApp: Screens
course_route.dart

Defines Application Routes


https://github.com/betsegawlemma/course_f
lutter_app/blob/main/lib/course/screens/c
ourse_route.dart
CourseApp: Course Model
Uses Equatable class for
equality comparison

Has fromJson method to


convert a JSON object
returned from REST API
request to Course object
CourseApp: Data Provider
We have a method
for each of the CRUD
operations
mentioned before

Uses http package


to interact with the
remote API (or to
perform the CRUD
requests)
CourseApp: Data Provider
The full code

https://github.com/betsegawlemma/course_flutter_ap
p/blob/main/lib/course/data_provider/course_data.dart
CourseApp: Repository
Just abstraction of the details of
the data provider layer

https://github.com/betsegawl
emma/course_flutter_app/blob
/main/lib/course/repository/
course_repository.dart
CourseApp: Bloc
course_event.dart

Defines the events

course_state.dart

Defines the states

course_bloc.dart

Maps Events to State

https://github.com/betsegawlemma/course_flu
tter_app/tree/main/lib/course/bloc
CourseApp: CourseEvent

Four Events
corresponding to the
four CRUD operations
CourseApp: CourseState

Three States
CourseApp: CourseBloc

When the CRUD events


happen, it generates
CourseLoadSuccess
state with the new
course list object
Barrel Files
You can manage imports using export

In each directory there is a .dart file named after


the directory name such as

screens.dart and course.dart


Barrel Files
These barrel files allows you to manage your imports nicely

You can minimize the number of imports in your files


BlocObserver
bloc_observer.dart

Contains a class named SimpleBlocObserver


which allows you to observe the transactions, for
example for debugging purpose

https://github.com/betsegawlemma/course_flutter_app/blob/main/lib/bloc_observer.dart
CourseApp
It is the root widget

It takes the CoureRepostory object as constructor argument


main.dart
The code on line 8, registers the BlocObserver
main.dart
The code on line 10 to 14 injects the data provider to the repository and the
http client to the data provider, then creates CourseRepository instance

Dependency Tree

CourseAPP

CourseRepository

CourseDataProvider

HttpClient
main.dart
The code on line 17 injects the course repository to the CourseApp and
creates CourseApp instance
Providing the Repository to the widget tree
The build method of CourseApp widget returns a MaterialApp widget

The CourseRepository instance is provided above the MaterialApp


Providing the Bloc to the widget tree
The CourseBloc instance is also provided above the MaterialApp

https://github.com/betsegawlemma/course_flutter_app/blob/main/lib/main.dart
Generating the CourseLoad Event
Inside the CourseApp while providing the CourseBloc to the tree we can
generate the first CourseLoad event
Consuming CourseLoadSuccess state
The default route for the application is CourseList screen

Inside this widget we check if the generated state is CourseLoadSuccess and


if it is, we display a list of course items inside a ListView as shown in the next
slide

When each item is tapped it navigates to the CourseDetail screen by


passing the current item as route argument
https://github.com/betsegawlemma/course_flutter_app/blob/main/lib/course/
screens/course_list.dart
UpdateCourse/CreateCourse Events
In the AddUpdateCourse widget you can find how the UpdateCourse or
CreateCourse events are generated when the save button is pressed

https://github.com/betsegawlemma/course_flutter_app/blob/mai
n/lib/course/screens/course_add_update.dart
DeleteCourse Event
Inside the CourseDetail widget when the delete button is pressed
CourseDelete event is generated
References
https://flutter.dev/docs/cookbook (Networking and Forms section)

https://bloclibrary.dev/

You might also like