0% menganggap dokumen ini bermanfaat (0 suara)
5 tayangan15 halaman

Panduan Lengkap Rest API dan Vania Framework

Dokumen ini menjelaskan tentang REST API dan Vania Framework, termasuk komponen utama, karakteristik, keuntungan, dan tantangan REST API. Selain itu, dokumen ini juga merinci struktur folder dan file dalam Vania Framework, serta memberikan contoh implementasi controller dan middleware. Vania adalah kerangka backend yang dirancang untuk pengembangan aplikasi web berkinerja tinggi menggunakan Dart.
Hak Cipta
© All Rights Reserved
Kami menangani hak cipta konten dengan serius. Jika Anda merasa konten ini milik Anda, ajukan klaim di sini.
Format Tersedia
Unduh sebagai PDF, TXT atau baca online di Scribd
0% menganggap dokumen ini bermanfaat (0 suara)
5 tayangan15 halaman

Panduan Lengkap Rest API dan Vania Framework

Dokumen ini menjelaskan tentang REST API dan Vania Framework, termasuk komponen utama, karakteristik, keuntungan, dan tantangan REST API. Selain itu, dokumen ini juga merinci struktur folder dan file dalam Vania Framework, serta memberikan contoh implementasi controller dan middleware. Vania adalah kerangka backend yang dirancang untuk pengembangan aplikasi web berkinerja tinggi menggunakan Dart.
Hak Cipta
© All Rights Reserved
Kami menangani hak cipta konten dengan serius. Jika Anda merasa konten ini milik Anda, ajukan klaim di sini.
Format Tersedia
Unduh sebagai PDF, TXT atau baca online di Scribd

Rest API

REST (Representational State Transfer) adalah gaya arsitektur yang digunakan untuk merancang layanan web yang memungkinkan interaksi
antara klien dan server. API (Application Programming Interface) adalah antar muka yang memungkinkan sistem saling berkomunikasi melalui
protokol HTTP/HTTPS dalam format terstruktur.

Komponen Utama Rest API


• Resources: Entitas utama yang diekspos oleh API, masing-masing diidentifikasi oleh URI unik.
• HTTP Methods: digunakan untuk CRUD pada sumber daya (GET, POST, PUT, DELETE).
• Representations: Format data Wewakili sumber daya (JSON, XML).
• Hypermedia Links: Tautan tertanam dalam respons untuk memungkinkan navigasi dinamis.
• Status Code: Menunjukan status permintaan (404 tidak ditemukan, 200 OK, dll)

Karakteristik Rest API


• Client-Server Architecture: memisahkan antarmuka pengguna klien dari penyimpanan data di server, sehingga meningkatkan
skalabilitas dan fleksibilitas.
• Stateless: setiap permintaan dari klien berisi semua infomasi yang diperlukan untuk di proses, membuat server tidak perlu menyimpan
sesi pengguna.
• Cacheable: respon dari server dapat di-cache oleh klien atau oleh perantara untuk meningkatkan kinerja.
• Uniform Interface: menyediakan antarmuka yang konsisten dan standar untuk memfasilitasi interaksi antara klien dan server.
• Leyered System: memungkinkan komponen tambahan (misal, load balancer, proxy) untuk meningkatkan skalabilitas dan keamanan
tanpa mempengaruhi interaksi klien-server.

Keuntungan Rest API


• Skalabilitas: REST API memungkinkan aplikasi untuk skala dengan mudah karena pemisahan antara klien dan server
• Fleksibilitas: dapat digunakan oleh berbagai jenis klien, termasuk web, mobile, dan aplikasi dekstop
• Portabilitas: Data dikirim dalam format standar seperti JSON atau XML, yang dapat dengan mudah digunakan oleh berbagai platform
dan bahasa pemograman.
• Kinerja: dukungan untuk caching respons dapat meningkatkan kinerja dan mengurangi beban server.

Tantangan Rest API


• Keamanan: REST API harus dirancang dengan mempertimbangkan keamanan, seperti otentikasi dan otorisasi, untuk melindungi data
sensitif.
• Pengelolaan Versi: mengelola versi API secara efektif untuk mendukung perubahan tanpa memutuskan kompatibilitas dengan klien
yang ada
• Dokumentasi: Menyediakan dokumentasi yang jelas dan lengkap untuk memudahkan pengembang dalam menggunakan API.

Vania Framework
Vania adalah kerangka backend tangguh yang dirancang untuk membangun aplikasi web berkinerja tinggi menggunakan Dart. Dengan
pendekatan langsung dan fitur-fitur canggih, Vania menyederhanakan proses pengembangan baik untuk pemula maupun pengembang
berpengalaman.

Fitur
• Skalabilitas: Dibuat untuk menangani lalu lintas tinggi, Vania dengan mudah melakukan skala seiring pertumbuhan aplikasi Anda.
• Ramah Pengembang: Nikmati API intuitif dan dokumentasi yang jelas, membuat pengembangan aplikasi web menjadi mudah.
• Perutean Sederhana: Tentukan dan kelola rute dengan mudah menggunakan sistem perutean Vania yang efisien, memastikan arsitektur
aplikasi yang kuat.
• Dukungan ORM: Berinteraksi secara lancar dengan database menggunakan sistem ORM Vania yang kuat, menyederhanakan
manajemen data.
• Validasi Data Permintaan: Validasi data permintaan masuk dengan mudah untuk menjaga integritas data dan meningkatkan keamanan.
• Migrasi Basis Data: Kelola dan terapkan perubahan skema dengan mudah menggunakan dukungan migrasi basis data bawaan Vania.

1
• WebSocket: Aktifkan komunikasi real-time antara server dan klien dengan dukungan WebSocket, sehingga meningkatkan pengalaman
pengguna.
• Antarmuka Baris Perintah (CLI): Sederhanakan tugas pengembangan dengan CLI sederhana Vania, menawarkan perintah untuk
membuat migrasi, menghasilkan model, dan banyak lagi.

1. bin/
Tujuan: Folder ini umumnya digunakan untuk menyimpan file skrip atau executable yang
digunakan untuk menjalankan aplikasi atau alat bantu.
Isi Folder: Skrip untuk memulai server atau menjalankan proses lain yang terkait dengan
aplikasi, misalnya skrip untuk pengaturan otomatis atau migrasi database.

2. lib/
Tujuan: Folder lib biasanya digunakan untuk menyimpan pustaka (library) atau modul-
modul yang berisi logika aplikasi yang dapat digunakan di berbagai bagian aplikasi. Ini
adalah tempat kode yang lebih reusable dan terorganisir.
Isi Folder: File Dart, JavaScript, Python, atau bahasa pemrograman lain yang berisi kelas,
fungsi, atau modul tertentu yang diimpor dan digunakan oleh bagian lain dari aplikasi.

3. public/
Tujuan: Folder public biasanya digunakan untuk menyimpan file statis yang dapat diakses
oleh klien (browser). Ini termasuk gambar, CSS, JavaScript, dan file lainnya yang tidak
memerlukan pemrosesan dinamis oleh server.
Isi Folder: Berisi file-file statis seperti: Gambar (misalnya logo, ikon), File CSS atau JavaScript
yang digunakan pada frontend, File HTML atau template yang digunakan oleh frontend
(jika diperlukan)

4. storage/
Tujuan: Folder storage digunakan untuk menyimpan file atau data yang berhubungan
dengan penyimpanan aplikasi, terutama file yang diunggah oleh pengguna atau file yang
perlu disimpan sementara atau permanen.
Isi Folder: Biasanya berisi file upload seperti gambar, dokumen, dan data lain yang
dihasilkan oleh aplikasi.

Ringkasan Struktur:
• bin/: Skrip untuk menjalankan aplikasi atau perintah lainnya.
• lib/: Kode modular atau pustaka yang berisi logika aplikasi.
• public/: File statis yang dapat diakses publik oleh browser (misalnya gambar, CSS, JS).
• storage/: Menyimpan file dinamis atau data yang diunggah oleh pengguna dan lainnya.

2
1. app/
Folder ini biasanya berisi berbagai komponen utama aplikasi, dibagi ke dalam
beberapa bagian.
• controllers/: Menyimpan file yang mengatur bagaimana aplikasi merespons
permintaan (request) dari pengguna. Biasanya, controller berisi logika untuk
menangani aksi tertentu, seperti menampilkan data atau mengolah input pengguna.
o Contoh: [Link] untuk mengatur pengelolaan pengguna (tambah,
edit, hapus).
• middleware/: Menyimpan file yang berfungsi sebagai perantara antara
permintaan pengguna dan respons aplikasi. Middleware bisa melakukan berbagai
tugas seperti otentikasi, validasi, atau logging sebelum permintaan diteruskan ke
controller.
o Contoh: [Link] untuk memeriksa apakah pengguna sudah login.
• models/: Menyimpan representasi data atau entitas dalam aplikasi, yang
biasanya berhubungan dengan database. Model mengatur cara data disimpan,
diambil, atau dimodifikasi.
o Contoh: [Link] untuk mendefinisikan struktur data pengguna dan
berinteraksi dengan database.
• providers/: Menyimpan file untuk mengatur dependensi atau layanan eksternal yang digunakan aplikasi, seperti pengaturan
layanan API, queue, atau pengelolaan cache.
o Contoh: [Link] untuk mengatur pengiriman email.
2. config/
Folder ini berisi pengaturan konfigurasi untuk aplikasi, seperti pengaturan database, pengaturan API, atau variabel lingkungan lainnya yang
dapat disesuaikan.
• Contoh: [Link] untuk pengaturan koneksi ke database atau [Link] untuk pengaturan umum aplikasi.
3. database/
Folder ini digunakan untuk pengaturan yang berhubungan dengan database, seperti migrasi schema, seeding data awal, atau pengaturan
koneksi database.
• Contoh: migrations/ untuk menyimpan file migrasi yang mengubah struktur database seiring waktu.
4. lang/
Folder ini biasanya berisi file bahasa untuk mendukung internasionalisasi atau lokalisasi aplikasi. Ini memungkinkan aplikasi untuk mendukung
berbagai bahasa dengan memisahkan teks yang digunakan di berbagai tempat.
• Contoh: [Link] untuk bahasa Inggris, [Link] untuk bahasa Indonesia, berisi teks-teks aplikasi seperti pesan kesalahan atau label.
5. route/
Folder ini berisi file yang mendefinisikan rute (routes) aplikasi. Rute menghubungkan URL yang diminta pengguna dengan fungsi atau
controller yang sesuai untuk menangani permintaan tersebut.
• Contoh: [Link] atau [Link] untuk mendefinisikan endpoint API yang dapat diakses oleh pengguna.

Ringkasan:
• app/: Berisi controller, middleware, model, dan provider yang menangani logika aplikasi.
• config/: Tempat menyimpan pengaturan aplikasi.
• database/: Berisi migrasi dan pengaturan database.
• lang/: Menyimpan file bahasa untuk lokalisasi.
• route/: Menyimpan rute untuk menentukan URL dan aksi yang sesuai.

3
.Env

File .env pada backend Vania biasanya merujuk pada file konfigurasi yang digunakan untuk menyimpan variabel lingkungan (environment
variables). Variabel ini berisi informasi sensitif atau pengaturan aplikasi yang berbeda untuk setiap lingkungan (misalnya, pengembangan,
staging, atau produksi).
Di dalam file .env, Anda bisa menyimpan data seperti:
• Kunci API
• Pengaturan database (misalnya URL, nama pengguna, dan kata sandi)
• Pengaturan lainnya yang bisa berbeda untuk setiap lingkungan

Struktur Migration
• Membuat tabel
• Ketik di terminal perintah:
• vania make:migration create_product_table
• Isikan atribut di file yang dibuat

4
5
Struktur Controllers
user_controller.dart
import 'package:vania/[Link]';
import 'package:vania_furniture_api/app/models/[Link]';

class UserController extends Controller {


Future<Response> index() async {
Map? user = Auth().user();
if (user != null) {
[Link]('password');
return [Link]({
'status': 'success',
'message': 'Data pengguna berhasil diambil',
'data': user,
});
} else {
return [Link]({
'status': 'error',
'message': 'Pengguna tidak terautentikasi',
}, 401);
}
}
Future<Response> updatePassword(Request request) async {
[Link]({
'current_password': 'required',
'password': 'required|min_length:6|confirmed'
}, {
'current_password.required': 'Password saat ini wajib diisi',
'[Link]': 'Password baru wajib diisi',
'password.min_length': 'Password baru harus memiliki minimal 6 karakter',
'[Link]': 'Konfirmasi password tidak cocok',
});

String currentPassword = [Link]('current_password');


Map<String, dynamic>? user = Auth().user();

if (user != null) {
if (Hash().verify(currentPassword, user['password'])) {
await User().query().where('id', '=', Auth().id()).update({
'password': Hash().make([Link]('password')),
});
return [Link]({
'status': 'success',
'message': 'Password berhasil diperbarui',
});
} else {
return [Link]({
'status': 'error',
'message': 'Password saat ini tidak cocok',
}, 401);
}
} else {
return [Link]({
'status': 'error',
'message': 'Pengguna tidak ditemukan',
}, 404);
}
}
Future<Response> create() async {
return [Link]({});
}
Future<Response> store(Request request) async {
return [Link]({});
}
Future<Response> show(int id) async {
return [Link]({});
}
Future<Response> edit(int id) async {
return [Link]({});
6
}
Future<Response> update(Request request, int id) async {
return [Link]({});
}
Future<Response> destroy(int id) async {
return [Link]({});
}
}
final UserController userController = UserController();

auth_controller.dart
import 'package:vania/[Link]';
import 'package:vania_furniture_api/app/models/[Link]';

class AuthController extends Controller {


Future<Response> register(Request request) async {
[Link]({
'name': 'required',
'email': 'required|email',
'password': 'required|min_length:6|confirmed',
}, {
'[Link]': 'nama tidak boleh kosong',
'[Link]': 'email tidak boleh kosong',
'[Link]': 'email tidak valid',
'[Link]': 'password tidak boleh kosong',
'password.min_length': 'password harus terdiri dari minimal 6 karakter',
'[Link]': 'konfirmasi password tidak sesuai',
});

final name = [Link]('name');


final email = [Link]('email');
var password = [Link]('password');

var user = await User().query().where('email', '=', email).first();


if (user != null) {
return [Link]({
"message": "user sudah ada",
}, 409);
}

password = Hash().make(password);
await User().query().insert({
"name": name,
"email": email,
"password": password,
"created_at": [Link]().toIso8601String(),
});

return [Link]({"message": "berhasil mendaftarkan user"}, 201);


}

Future<Response> login(Request request) async {


[Link]({
'email': 'required|email',
'password': 'required',
}, {
'[Link]': 'email tidak boleh kosong',
'[Link]': 'email tidak valid',
'[Link]': 'password tidak boleh kosong',
});

final email = [Link]('email');


var password = [Link]('password').toString();

var user = await User().query().where('email', '=', email).first();


if (user == null) {
return [Link]({
"message": "user belum terdaftar",
}, 409);
}
if (!Hash().verify(password, user['password'])) {
7
return [Link]({
"message": "kata sandi yang anda masukan salah",
}, 401);
}

final token = await Auth()


.login(user)
.createToken(expiresIn: Duration(days: 30), withRefreshToken: true);

return [Link]({
"message": "berhasil login",
"token": token,
});
}
}
final AuthController authController = AuthController();

todo_controller.dart
import 'package:vania/[Link]';
import 'package:vania_furniture_api/app/models/[Link]';

class TodoController extends Controller {


Future<Response> index() async {
return [Link]({'message': 'Hello World'});
}

Future<Response> store(Request request) async {


[Link]({
'title': 'required',
'description': 'required',
}, {
'[Link]': 'Judul todo wajib diisi',
'[Link]': 'Deskripsi todo wajib diisi',
});

Map<String, dynamic> data = [Link]();


Map<String, dynamic>? user = Auth().user();

if (user != null) {
var todo = await Todo().query().create({
'user_id': Auth().id(),
'title': data['title'],
'description': data['description'],
});
return [Link]({
'status': 'success',
'message': 'Todo berhasil dibuat',
'data': todo,
}, 201);
} else {
return [Link]({
'status': 'error',
'message': 'Pengguna tidak terautentikasi',
}, 401);
}
}
Future<Response> show(int id) async {

8
return [Link]({});
}
Future<Response> edit(int id) async {
return [Link]({});
}
Future<Response> update(Request request, int id) async {
return [Link]({});
}
Future<Response> destroy(int id) async {
return [Link]({});
}
}
final TodoController todoController = TodoController();

Struktur Middleware
[Link]

Home_middleware.dart

Error_response_middleware.dart

9
Struktur Models
[Link]

Struktur Routes

10
11
• Jika membuat project Frontend dari awal, lakukan konfigurasi berikut
• Membuat tampilan sederhana login
• Setting file [Link]

Login_screen.dart
import 'package:client_user/service/[Link]';
import 'package:flutter/[Link]';

class LoginScreen extends StatefulWidget {


const LoginScreen({[Link]});

@override
State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {


final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
bool _isLoading = false;

void handleLogin() async {


setState(() {
_isLoading = true;
});

try {
await login(_emailController.text, _passwordController.text);
[Link](context).showSnackBar(
const SnackBar(content: Text("Login berhasil!")),
);
} catch (e) {
[Link](context).showSnackBar(
SnackBar(content: Text("Login gagal: $e")),
);
} finally {
setState(() {
_isLoading = false;
});
}
}

12
void handleFetchData() async {
try {
await fetchProtectedData();
} catch (e) {
[Link](context).showSnackBar(
SnackBar(content: Text("Gagal mengambil data: $e")),
);
}
}

void handleHapusToken() async {


try {
await logout();
[Link](context).showSnackBar(
const SnackBar(content: Text("Access token berhasil dihapus!")),
);
} catch (e) {
[Link](context).showSnackBar(
SnackBar(content: Text("Gagal menghapus token: $e")),
);
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Login"),
),
body: Padding(
padding: const [Link](16.0),
child: Column(
crossAxisAlignment: [Link],
children: [
TextField(
controller: _emailController,
decoration: const InputDecoration(labelText: "Email"),
),
TextField(
controller: _passwordController,
decoration: const InputDecoration(labelText: "Password"),
obscureText: true,
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _isLoading ? null : handleLogin,
child: Text(_isLoading ? "Loading..." : "Login"),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: handleFetchData,
child: const Text("Fetch Data"),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: handleHapusToken,
child: const Text("Hapus Access Token"),
),
],
),
),
);
}
}

13
[Link]
import 'dart:convert';
import 'package:http/[Link]' as http;
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

const secureStorage = FlutterSecureStorage();

const String baseUrl = '[Link]

Future<Map<String, String>> getDefaultHeaders() async {


final accessToken = await [Link](key: 'access_token');
return {
'Content-Type': 'application/json',
if (accessToken != null) 'Authorization': 'Bearer $accessToken',
};
}

Future<void> login(String email, String password) async {


final url = [Link]('$baseUrl/auth/login');

try {
final response = await [Link](
url,
headers: {
'Content-Type': 'application/json',
},
body: [Link]({
'email': email,
'password': password,
}),
);

if ([Link] == 200) {
final data = [Link]([Link]);
final accessToken = data['token']['access_token'];

await [Link](key: 'access_token', value: accessToken);


print('Access token successfully stored!');
} else {
final error = [Link]([Link]);
throw Exception('Login failed: ${error['message'] ?? 'Server error'}');
}
} catch (e) {
throw Exception('Login failed: $e');
}
}

Future<void> fetchProtectedData() async {


final url = [Link]('$baseUrl/user/me');
final accessToken = await [Link](key: 'access_token');

try {
final response = await [Link](
url,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
},
);

if ([Link] == 200) {
print('Data retrieved successfully: ${[Link]}');
} else if ([Link] == 401) {
print('Invalid or expired access token. Please log in again.');
} else {
final error = [Link]([Link]);
print('Error: ${error['message'] ?? 'Server error'}');
}
} catch (e) {
print('An error occurred: $e');
}

14
}

Future<void> logout() async {


await [Link](key: 'access_token');
print('Access token successfully deleted.');
}

15

Anda mungkin juga menyukai