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?
In this case, we do not require an interface or trait because we only have a single observer, the Subscriber. Typically, interfaces or traits are used when dealing with multiple types of observers grouped into different classes. However, here, a single struct is sufficient to meet the requirements.
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?
Using a Dashmap is highly important in this case because it allows us to access the Subscriber by its unique URL. This is crucial for the notification process, as we need to send notifications to specific subscribers based on their URLs. If we were to use a Vec, we would have to iterate through the entire list to find the correct subscriber, which would be inefficient and time-consuming.
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? Using a static singleton DashMap ensures thread safety throughout the entire process by guaranteeing that only one thread can access the shared resource at a time. The Singleton pattern ensures that all subscribers remain synchronized effectively.
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?
By separating Model, Service, and Repository, we can achieve a cleaner and more organized code structure. This separation allows us to isolate the data access logic (Repository) from the business logic (Service), making it easier to maintain and test each component independently. Additionally, this separation promotes reusability and scalability (SRP Principal), as we can easily modify or replace one component without affecting the others.
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?
Without any separation between Service and Repository, all of the workload of the main application logic will be handled by the Model. This will lead to a monolithic structure where all the logic is tightly coupled, making it difficult to maintain and test. The complexity of the code will increase significantly as more features are added, leading to a higher chance of bugs and errors. Additionally, it will be harder to understand the flow of the application, as all the logic is mixed together in one place.
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 a powerful tool that allows us to test our API endpoints easily. It provides a user-friendly interface to send HTTP requests and view the responses, errors, and status codes.
Reflection Publisher-3
Observer Pattern has two variations: Push model (publisher pushes data to subscribers) and Pull model (subscribers pull data from publisher). In this tutorial case, which variation of Observer Pattern that we use?
In this case, we used the Push Model, indicated by the fact that the publisher sends notifications to subscribers whenever a new product is created or deleted. The subscribers do not need to request the data; they receive it automatically when the publisher sends it.
What are the advantages and disadvantages of using the other variation of Observer Pattern for this tutorial case? (example: if you answer Q1 with Push, then imagine if we used Pull)
The Pull model has its own advantages and disadvantages. One advantage is that it allows subscribers to control when they want to receive updates, which can be useful in certain scenarios. However, this can also lead to increased complexity, as subscribers need to implement their own logic to pull data from the publisher. Additionally, it may result in delays in receiving updates, as subscribers may not always be checking for new data.
Explain what will happen to the program if we decide to not use multi-threading in the notification process. If we do not use multi-threading in the notification process, the program will become blocked while waiting for each notification to be sent. This means that if one subscriber takes a long time to respond, all other subscribers will also be delayed. This can lead to a poor user experience and may cause timeouts or errors if the notification process takes too long.