Tutorial and Example for Advanced Programming 2024 - Faculty of Computer Science, Universitas Indonesia
In this repository, we have provided you a REST (REpresentational State Transfer) API project using Rocket web framework.
This project consists of four modules:
controller: this module contains handler functions used to receive request and send responses. In Model-View-Controller (MVC) pattern, this is the Controller part.model: this module contains structs that serve as data containers. In MVC pattern, this is the Model part.service: this module contains structs with business logic methods. In MVC pattern, this is also the Model part.repository: this module contains structs that serve as databases and methods to access the databases. You can use methods of the struct to get list of objects, or operating an object (create, read, update, delete).
This repository provides a basic functionality that makes BambangShop work: ability to create, read, and delete Products.
This repository already contains a functioning Product model, repository, service, and controllers that you can try right away.
As this is an Observer Design Pattern tutorial repository, you need to implement another feature: Notification.
This feature will notify creation, promotion, and deletion of a product, to external subscribers that are interested of a certain product type.
The subscribers are another Rocket instances, so the notification will be sent using HTTP POST request to each subscriber's receive notification address.
You can download the Postman Collection JSON here: https://ristek.link/AdvProgWeek7Postman
After you download the Postman Collection, you can try the endpoints inside "BambangShop Publisher" folder.
This Postman collection also contains endpoints that you need to implement later on (the Notification feature).
Postman is an installable client that you can use to test web endpoints using HTTP request. You can also make automated functional testing scripts for REST API projects using this client. You can install Postman via this website: https://www.postman.com/downloads/
- Set up environment variables first by creating
.envfile. Here is the example of.envfile:Here are the details of each environment variable:APP_INSTANCE_ROOT_URL="http://localhost:8000"variable type description APP_INSTANCE_ROOT_URL string URL address where this publisher instance can be accessed. - Use
cargo runto run this app. (You might want to usecargo checkif you only need to verify your work without running the app.)
- Clone https://gitlab.com/ichlaffterlalu/bambangshop to a new repository.
- STAGE 1: Implement models and repositories
- Commit:
Create Subscriber model struct. - Commit:
Create Notification model struct. - Commit:
Create Subscriber database and Subscriber repository struct skeleton. - Commit:
Implement add function in Subscriber repository. - Commit:
Implement list_all function in Subscriber repository. - Commit:
Implement delete function in Subscriber repository. - Write answers of your learning module's "Reflection Publisher-1" questions in this README.
- Commit:
- STAGE 2: Implement services and controllers
- Commit:
Create Notification service struct skeleton. - Commit:
Implement subscribe function in Notification service. - Commit:
Implement subscribe function in Notification controller. - Commit:
Implement unsubscribe function in Notification service. - Commit:
Implement unsubscribe function in Notification controller. - Write answers of your learning module's "Reflection Publisher-2" questions in this README.
- Commit:
- STAGE 3: Implement notification mechanism
- Commit:
Implement update method in Subscriber model to send notification HTTP requests. - Commit:
Implement notify function in Notification service to notify each Subscriber. - Commit:
Implement publish function in Program service and Program controller. - Commit:
Edit Product service methods to call notify after create/delete. - Write answers of your learning module's "Reflection Publisher-3" questions in this README.
- Commit:
This is the place for you to write reflections:
-
Dalam kasus ini, penggunaan interface (trait) tidak diperlukan, dan cukup dengan satu Model struct saja. Alasannya, hanya ada satu observer, yaitu class Subscriber, sehingga tidak ada kebutuhan untuk mendukung berbagai jenis observer. Interface akan lebih berguna jika terdapat banyak observer dengan tipe yang berbeda-beda, yang memerlukan fleksibilitas dalam implementasi.
-
Saya rasa penggunaan DashMap sudah tepat. Jika menggunakan Vec, kita harus membuat dua array terpisah untuk menyimpan id dan url, serta melakukan iterasi untuk menemukan pasangan nilai tersebut. Dengan DashMap, kita dapat menyimpan id dan url dalam satu struktur, sehingga lebih efisien dan mudah digunakan.
-
Aplikasi BambangShop menggunakan multi-threading, sehingga lebih baik menggunakan DashMap dibandingkan dengan Singleton pattern. DashMap adalah thread-safe HashMap yang mendukung concurrent access, memungkinkan data SUBSCRIBERS diakses secara bersamaan tanpa masalah. Sebaliknya, pendekatan Singleton pattern hanya menciptakan satu instance selama program berjalan, yang dalam lingkungan multi-threading memerlukan mekanisme locking. Hal ini dapat meningkatkan kompleksitas kode dan berisiko menyebabkan deadlock, sehingga penggunaan DashMap menjadi pilihan yang lebih efisien.
- Untuk meningkatkan maintainability, serta memastikan modularity dan scalability, kita menerapkan prinsip Single Responsibility, di mana setiap class hanya memiliki satu tanggung jawab. Dengan memisahkan Service dan Repository dari Model, kita dapat memisahkan business logic dari data access, sehingga kode menjadi lebih terstruktur, lebih mudah diuji (testable), dan lebih sederhana untuk di-debug.
- Akibatnya, kode akan menjadi lebih kompleks dan sulit untuk di-maintain. Tingkat coupling antara kedua class akan semakin tinggi, sehingga setiap perubahan dapat berdampak luas dibandingkan jika business logic dan data access dipisahkan. Hal ini dapat menyulitkan pengembangan dan meningkatkan risiko error dalam sistem.
- Dengan Postman, saya dapat menguji API secara efisien, memeriksa hasil dari setiap request, dan memastikan bahwa response yang diterima sudah sesuai dengan ekspektasi. Salah satu fitur utamanya adalah Collection, yang memungkinkan pengelompokan request ke dalam folder agar lebih terorganisir. Selain itu, fitur Environment memungkinkan penyimpanan variabel yang sering digunakan, sehingga mempermudah pengujian tanpa perlu mengubah nilai secara manual.
- Tutorial ini menggunakan variasi Observer Pattern dengan pendekatan Push Model, di mana Publisher secara langsung mengirimkan notifikasi ke seluruh Subscriber setiap kali terjadi CRUD pada Product melalui pemanggilan method notify pada NotificationService.
- Pull Model:
-
Keuntungan: Observer/Subscriber memiliki kendali atas notifikasi yang diterima dari Publisher, memungkinkan mereka memilih informasi yang diinginkan (lebih fleksibel).
-
Kelemahan: Observer/Subscriber harus aktif dalam mengambil data. Jika tidak, mereka bisa saja melewatkan notifikasi yang diharapkan karena perlu melakukan pull secara manual.
- Proses akan berjalan secara sekuensial dan memerlukan waktu yang lama. Bottle-neck terjadi ketika Publisher mengirimkan notifikasi ke seluruh Subscriber dalam method notify() pada class NotificationService. Akibatnya, pengiriman notifikasi harus selesai terlebih dahulu sebelum proses lain dapat dilanjutkan.