BambangShop Publisher App
Tutorial and Example for Advanced Programming 2024 - Faculty of Computer Science, Universitas Indonesia
About this Project
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 Product
s.
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.
API Documentations
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/
How to Run in Development Environment
- Set up environment variables first by creating
.env
file. Here is the example of.env
file: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 run
to run this app. (You might want to usecargo check
if you only need to verify your work without running the app.)
Mandatory Checklists (Publisher)
- 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:
Your Reflections
This is the place for you to write reflections:
Mandatory (Publisher) Reflections
Reflection Publisher-1
- In the Observer pattern diagram explained by the Head First Design Pattern book, Subscriber is defined as an interface. Explain based on your understanding of Observer design patterns, do we still need an interface (or trait in Rust) in this BambangShop case, or a single Model struct is enough?
Using an interface (or trait in Rust) for the Subscriber in the Observer pattern creates a more extensible and scalable codebase that follows SOLID principles. Specifically, it supports the Open/Closed principle by allowing new subscribers without modifying existing code, and follows Dependency Inversion by having Publishers depend on abstractions rather than concrete implementations. While our current example is simple without planned extensions, meaning a single Model struct would technically work, implementing a proper interface/trait is still recommended as best practice to ensure future flexibility and maintainability.
- id in Program and url in Subscriber is intended to be unique. Explain based on your understanding, is using Vec (list) sufficient or using DashMap (map/dictionary) like we currently use is necessary for this case?
For elements with unique identifiers like subscriber URLs or program IDs, DashMap provides significant efficiency advantages over Vec. DashMap offers O(1) constant-time lookups compared to Vec's O(n) linear search time complexity. This performance difference becomes increasingly important as the collection grows. Using DashMap is therefore necessary for this case to maintain efficiency at scale and enable quick lookups by unique identifiers.
- When programming using Rust, we are enforced by rigorous compiler constraints to make a thread-safe program. In the case of the List of Subscribers (SUBSCRIBERS) static variable, we used the DashMap external library for thread safe HashMap. Explain based on your understanding of design patterns, do we still need DashMap or we can implement Singleton pattern instead?
The Singleton pattern and DashMap serve complementary purposes rather than being alternatives. The lazy_static macro already provides Singleton functionality by ensuring only one instance of the collection exists with global access. However, Singleton alone doesn't address thread safety concerns with concurrent access. DashMap specifically handles safe concurrent access to the HashMap, preventing race conditions and other concurrency issues. Therefore, both are needed: the Singleton pattern (via lazy_static) prevents redundant instantiation, while DashMap ensures thread-safe operations on the shared resource.
Reflection Publisher-2
- In the Model-View Controller (MVC) compound pattern, there is no “Service” and “Repository”. Model in MVC covers both data storage and business logic. Explain based on your understanding of design principles, why we need to separate “Service” and “Repository” from a Model?
Separating Service and Repository from the Model is essential to maintain compliance with the Single Responsibility Principle (SRP) and Separation of Concerns. In a well-designed system, the Model represents the database data structure, the Repository handles data access and modification operations, and the Service implements the business logic. This separation creates a more modular codebase that's easier to maintain and extend, as new services or repositories can be added without modifying existing code. Additionally, this approach significantly improves testability by allowing each component to be tested in isolation. Overall, this separation is necessary to ensure clean architecture that adheres to fundamental design principles.
- What happens if we only use the Model? Explain your imagination on how the interactions between each model (Program, Subscriber, Notification) affect the code complexity for each model?
Using only the Model to handle both data storage and business logic would create a less modular and harder-to-maintain codebase. This approach would directly violate the Single Responsibility Principle by forcing the Model to take on multiple distinct responsibilities. The interactions between Program, Subscriber, and Notification models would become increasingly complex as each model would need to manage both its own data representation and the business logic for interacting with other models. This would inevitably lead to highly coupled code with increased complexity, making the system more difficult to debug, test, and extend in the future.
- Have you explored more about Postman? Tell us how this tool helps you to test your current work. You might want to also list which features in Postman you are interested in or feel like it is helpful to help your Group Project or any of your future software engineering projects.
Postman is an invaluable tool for testing web endpoints through HTTP requests. It allows for rapid testing of web application functionality without writing additional code. Some of the most useful features include the ability to save requests and responses for future reference, simple control over request headers and body content, and effective cookie management. Postman also offers excellent API documentation capabilities, making it easier to share endpoint information with other developers. This tool has been tremendously helpful for testing our web application endpoints, and I plan to continue using it in future software engineering projects as it streamlines the API testing process significantly.