Agenda
- Call REST API with GET Method
- Call REST API with POST Method
- JSON Serialization (jsonEncode)
- JSON Deserializaton (jsonDecode)
- Call Authorized REST API with JWT
Prerequisite
1. สร้างโปรเจ็ค แล้ว migrate ให้ dart ซัพพอร์ท null safety
dart create rest_api cd rest_api dart migrate --apply-changes
2. ติดตั้ง http package
dart pub add http
เข้าไปดูได้ที่ https://pub.dev/packages/http
3. เตรียม API
ผมทำเอาไว้เพื่อทดสอบแล้วที่ https://techcoach.azurewebsites.net
4. ตัวอย่างที่ 1 การเรียก API แบบ GET กับการดึงค่า Gender
URL: https://techcoach.azurewebsites.net/registration/genders
4.1 import http,io,convert package แล้วสร้างฟังชั่น getGender แบบ async
import 'package:http/http.dart' as http; import 'dart:io'; import 'dart:convert'; void main(List<String> arguments) { } Future getGenders() async { }
4.2 เขียนโปรแกรมที่ฟังชั่น getGenders เรียกฟังชั่น http.get แล้วส่ง URL เข้าไปดังนี้
final response = await http.get( Uri.parse('https://techcoach.azurewebsites.net/registration/genders'), );
4.2 ตรวจสอบว่าถ้าสถานะไม่ใช่ ok (200) ก็จะหยุดการทำงาน
if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; }
4.3 พิมพ์ผลที่ได้ออกมาดูก่อน
print(response.body);
4.3 เปลี่ยนที่ฟังชั่น main เป็นแบบ async แล้วเรียกฟังชั่น getGenders
void main(List<String> arguments) async { await getGenders(); }
ผลลัพธ์ที่ได้หลังจากการรันคำสั่ง
dart run [{"id":1,"name":"ชาย"},{"id":2,"name":"หญิง"}]
4.4 สร้างคลาส Gender โดยมี id กับ name เป็น arribute พร้อมกับสร้าง constructor เพื่อรับค่าด้วย
class Gender { final int id; final String name; Gender({ required this.id, required this.name, }); }
4.4 เพิ่ม factory constructor ให้กับ Gender เพื่อความสะดวกในการแปลงจาก Map เป็น Object
class Gender { final int id; final String name; Gender({ required this.id, required this.name, }); factory Gender.fromJson(Map<String, dynamic> json) => Gender( id: json['id'], name: json['name'], ); }
4.5 แก้ไขฟังชั่น getGenders ลบบรรทัด print ออกแล้วเพิ่มคำสั่ง jsonDecode เพื่อแปลงจาก JSON String ให้เป็น List ของ Map
final json = jsonDecode(response.body) as List;
4.6 ใช้ map เพื่อแปลงจาก Map ให้กลายเป็น List ของ Gender
final genders = json.map((e) => Gender.fromJson(e)).toList();
4.6 แสดงผลที่ได้จาก List ของ Gender
for (var gender in genders) { print('id: ${gender.id}, name: ${gender.name}'); }
ผลลัพธ์ที่ได้หลังจากการรันคำสั่ง
dart run id: 1, name: ชาย id: 2, name: หญิง
import 'package:http/http.dart' as http; import 'dart:io'; import 'dart:convert'; void main(List<String> arguments) async { await getGenders(); } Future getGenders() async { final response = await http.get( Uri.parse('https://techcoach.azurewebsites.net/registration/genders'), ); if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } final json = jsonDecode(response.body) as List; final genders = json.map((e) => Gender.fromJson(e)).toList(); for (final gender in genders) { print('id: ${gender.id}, name: ${gender.name}'); } } class Gender { int id; String name; Gender({ required this.id, required this.name, }); factory Gender.fromJson(Map<String, dynamic> json) => Gender( id: json['id'], name: json['name'], ); }
5. ตัวอย่างที่ 2 การเรียก API แบบ POST กับการลงทะเบียน User โดยจะต้องส่ง payload ในรูปแบบ JSON ที่ body ด้วย
URL: https://techcoach.azurewebsites.net/registration/users
5.1 สร้างฟังชั่น signup แบบ async รับพารามิเตอร์ที่ต้องการ แล้วเรียกฟังชั่น http.post แล้วส่ง URL เข้าไปดังนี้
Future signup({ required final String firstName, required final String lastName, required final String email, required final String password, required final int genderId, }) async { final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/users'), ); }
5.2 เพิ่ม content-type: application/json เข้าไปที่ headers
final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/users'), headers: {'content-type': 'application/json'}, );
5.3 ที่ body สร้าง Map ของคีย์ต่างๆที่ payload ต้องการ แล้วใช้ jsonEncode เพื่อแปลงจาก Map ให้เป็น JSON String
final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/users'), headers: {'content-type': 'application/json'}, body: jsonEncode({ 'firstName': firstName, 'lastName': lastName, 'email': email, 'password': password, 'genderId': genderId, }), );
5.4 ตรวจสอบว่าถ้าสถานะ ok (200) แสดงผลคำว่า signup success
if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } print('signup success');
5.5 ที่ฟังชั่น main ให้เรียกฟังชั่น signup ตัวอย่างดังนี้
void main(List<String> arguments) async { await signup( firstName: 'Code', lastName: 'Bangkok', email: 'codebangkok@gmail.com', password: 'iloveyou', genderId: 1, ); }
ผลลัพธ์ที่ได้หลังจากการรันคำสั่ง
dart run signup success
โค้ดที่เกี่ยวข้องทั้งหมด
import 'package:http/http.dart' as http; import 'dart:io'; import 'dart:convert'; void main(List<String> arguments) async { await signup( firstName: 'Code', lastName: 'Bangkok', email: 'codebangkok@gmail.com', password: 'iloveyou', genderId: 1, ); } Future signup({ required final String firstName, required final String lastName, required final String email, required final String password, required final int genderId, }) async { final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/users'), headers: {'content-type': 'application/json'}, body: jsonEncode({ 'firstName': firstName, 'lastName': lastName, 'email': email, 'password': password, 'genderId': genderId, }), ); if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } print('signup success'); }
6. ตัวอย่างที่ 3 การเรียก API แบบ POST กับการ Login โดยจะต้องส่ง payload ในรูปแบบ JSON ที่ body และรับค่า response กลับมาด้วย
URL: https://techcoach.azurewebsites.net/registration/login
6.1 สร้างฟังชั่น login แบบ async รับพารามิเตอร์ที่ต้องการ แล้วเรียกฟังชั่น http.post แล้วส่ง URL เข้าไปดังนี้
Future login({ required final String email, required final String password, }) async { final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/login'), ); }
6.2 เพิ่ม content-type: application/json เข้าไปที่ headers
final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/login'), headers: {'content-type': 'application/json'}, );
6.3 ที่ body สร้าง Map ของคีย์ต่างๆที่ payload ต้องการ แล้วใช้ jsonEncode เพื่อแปลงจาก Map ให้เป็น JSON String
final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/login'), headers: {'content-type': 'application/json'}, body: jsonEncode({ 'email': email, 'password': password, }), );
6.4 ตรวจสอบว่าถ้าสถานะไม่ใช่ ok (200) ก็จะหยุดการทำงาน
if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; }
6.5 สร้างคลาส User โดยมี arribute ต่างๆตาม response พร้อมกับสร้าง constructor เพื่อรับค่าด้วย
class User { final int id; final String firstName; final String lastName; final String email; final Gender gender; final String jwtToken; User({ required this.id, required this.firstName, required this.lastName, required this.email, required this.gender, required this.jwtToken, }); }
6.6 เพิ่ม factory constructor ให้กับ User เพื่อความสะดวกในการแปลงจาก Map เป็น Object
class User { final int id; final String firstName; final String lastName; final String email; final Gender gender; final String jwtToken; User({ required this.id, required this.firstName, required this.lastName, required this.email, required this.gender, required this.jwtToken, }); factory User.fromJson(Map<String, dynamic> json) => User( id: json['id'], firstName: json['firstName'], lastName: json['lastName'], email: json['email'], gender: Gender.fromJson(json['gender']), jwtToken: json['jwtToken'], ); }
6.7 แก้ไขฟังชั่น login เพิ่มคำสั่ง jsonDecode เพื่อแปลงจาก JSON String ไปเป็น Map
final json = jsonDecode(response.body);
6.8 แปลงจาก Map ให้กลายเป็น User object ด้วย fromJson
final user = User.fromJson(json);
6.9 แสดงผลที่ได้จาก User object
print('First Name: ${user.firstName}'); print('Last Name: ${user.lastName}'); print('Email: ${user.email}'); print('Gender: ${user.gender.name}'); print('JWT Token: ${user.jwtToken}');
6.10 ที่ฟังชั่น main ให้เรียกฟังชั่น login ตัวอย่างดังนี้
void main(List<String> arguments) async { await login( email: 'codebangkok@gmail.com', password: 'iloveyou', ); }
ผลลัพธ์ที่ได้หลังจากการรันคำสั่ง (jwt token จะเปลี่ยนทุกครั้งที่รัน)
dart run First Name: Code Last Name: Bangkok Email: codebangkok@gmail.com Gender: ชาย JWT Token: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJJZCI6IjYiLCJzdWIiOiJjb2RlYmFuZ2tva0BnbWFpbC5jb20iLCJlbWFpbCI6ImNvZGViYW5na29rQGdtYWlsLmNvbSIsIm5iZiI6MTYxOTY5MDkwMSwiZXhwIjoxNjE5NzEyNTAxLCJpYXQiOjE2MTk2OTA5MDF9.BBQ6RDSIZodGdn19Af5HrZLHSyGOJJReXAsSXfN2LG1dc4kTK6SlLc6U7e65-9iSBqiM4MA97EMvJvRUYKbUwQ
โค้ดที่เกี่ยวข้องทั้งหมด
import 'package:http/http.dart' as http; import 'dart:io'; import 'dart:convert'; void main(List<String> arguments) async { await login( email: 'codebangkok@gmail.com', password: 'iloveyou', ); } Future login({ required final String email, required final String password, }) async { final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/login'), headers: {'content-type': 'application/json'}, body: jsonEncode({ 'email': email, 'password': password, }), ); if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } final json = jsonDecode(response.body); final user = User.fromJson(json); print('First Name: ${user.firstName}'); print('Last Name: ${user.lastName}'); print('Email: ${user.email}'); print('Gender: ${user.gender.name}'); print('JWT Token: ${user.jwtToken}'); } class User { final int id; final String firstName; final String lastName; final String email; final Gender gender; final String jwtToken; User({ required this.id, required this.firstName, required this.lastName, required this.email, required this.gender, required this.jwtToken, }); factory User.fromJson(Map<String, dynamic> json) => User( id: json['id'], firstName: json['firstName'], lastName: json['lastName'], email: json['email'], gender: Gender.fromJson(json['gender']), jwtToken: json['jwtToken'], ); }
7. ตัวอย่างที่ 4 การเรียก Authorized API แบบ GET ด้วยการใช้ JWT Token
URL: https://techcoach.azurewebsites.net/registration/users
7.1 สร้างฟังชั่น getUsers แบบ async รับ jwt token เข้ามา แล้วเรียกฟังชั่น http.get แล้วส่ง URL เข้าไปดังนี้
Future getUsers({required String jwtToken}) async { final response = await http.get( Uri.parse('https://techcoach.azurewebsites.net/registration/users'), ); }
7.2 เพิ่ม Authorization: Bearer เข้าไปที่ headers นำค่า jwt token ที่ได้จากการ login มาใส่
final response = await http.get( Uri.parse('https://techcoach.azurewebsites.net/registration/users'), headers: {'authorization': 'Bearer $jwtToken'}, );
7.3 ตรวจสอบว่าถ้าสถานะ ok (200) ก็พิมพ์ผลลัพธ์ที่ได้ออกมาดู
if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } print(response.body);
7.4 ที่ฟังชั่น main ให้เรียกฟังชั่น getUsers ตัวอย่างดังนี้
void main(List<String> arguments) async { final jwtToken = ''; //นำค่า jwt ที่ได้จากการ login มาใส่ที่นี่ await getUsers(jwtToken: jwtToken); }
ผลลัพธ์ที่ได้หลังจากการรันคำสั่ง
dart run [{"id":1,"firstName":"Code","lastName":"Bangkok","email":"codebangkok@gmail.com","gender":{"id":1,"name":"ชาย"}}]
โค้ดทั้งหมด
import 'package:http/http.dart' as http; import 'dart:io'; import 'dart:convert'; void main(List<String> arguments) async { final jwtToken = ''; //นำค่า jwt ที่ได้จากการ login มาใส่ที่นี่ await getUsers(jwtToken: jwtToken); } Future getUsers({required String jwtToken}) async { final response = await http.get( Uri.parse('https://techcoach.azurewebsites.net/registration/users'), headers: {'authorization': 'Bearer $jwtToken'}, ); if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } print(response.body); } Future login({ required final String email, required final String password, }) async { final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/login'), headers: {'content-type': 'application/json'}, body: jsonEncode({ 'email': email, 'password': password, }), ); if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } final json = jsonDecode(response.body); final user = User.fromJson(json); print('First Name: ${user.firstName}'); print('Last Name: ${user.lastName}'); print('Email: ${user.email}'); print('Gender: ${user.gender.name}'); print('JWT Token: ${user.jwtToken}'); } Future signup({ required final String firstName, required final String lastName, required final String email, required final String password, required final int genderId, }) async { final response = await http.post( Uri.parse('https://techcoach.azurewebsites.net/registration/users'), headers: {'content-type': 'application/json'}, body: jsonEncode({ 'firstName': firstName, 'lastName': lastName, 'email': email, 'password': password, 'genderId': genderId, }), ); if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } print('signup success'); } Future getGenders() async { final response = await http.get( Uri.parse('https://techcoach.azurewebsites.net/registration/genders'), ); if (response.statusCode != HttpStatus.ok) { print('Response: ${response.statusCode}'); return; } final json = jsonDecode(response.body) as List; final genders = json.map((e) => Gender.fromJson(e)).toList(); for (final gender in genders) { print('id: ${gender.id}, name: ${gender.name}'); } } class Gender { final int id; final String name; Gender({ required this.id, required this.name, }); factory Gender.fromJson(Map<String, dynamic> json) => Gender( id: json['id'], name: json['name'], ); } class User { final int id; final String firstName; final String lastName; final String email; final Gender gender; final String jwtToken; User({ required this.id, required this.firstName, required this.lastName, required this.email, required this.gender, required this.jwtToken, }); factory User.fromJson(Map<String, dynamic> json) => User( id: json['id'], firstName: json['firstName'], lastName: json['lastName'], email: json['email'], gender: Gender.fromJson(json['gender']), jwtToken: json['jwtToken'], ); }
ติดตามผลงานได้ที่
- Page: https://fb.com/CodeBangkok
- Group: https://fb.com/groups/msdevth
- Blog: https://dev.to/codebangkok
- YouTube: https://youtube.com/CodeBangkok
Top comments (0)