Myapp has several features that you can activate/deactivate using environment variables. It also has some communication patterns like API, RPC, or Event.
First, you have Frontend and API.
Frontend is intended to be accessed by users. It has buttons, links, and a nice user interface. This user interface usually needs to access API endpoints to translate user action into server requests.
Aside from the Frontend, the API endpoints are also accessible by external systems. You might have third-party client apps, webhook, or even IOT devices.
In Myapp, most API requests will be translated into events/RPC calls. The difference between events and RPC calls is as follows:
- Event
- Once an event is fired, event handlers will pick up the message.
- Myapp will not wait for the process to be completed. It just fires the event, lets the event handler handles the message, and continues with other processes.
- You usually use events if you don't need an immediate response. For example:
- You train a machine learning model. The process can take hours or even days. You just want to trigger the training, and you don't need immediate results. Once the training has been completed, you can let the event handler send a notification email to the user.
- You deal with warehouse fulfillment progress. The fulfillment might take a very long time, you can't make sure that the user will get immediate feedback.
- RPC (Remote procedure call)
- Once an RPC call is fired, RPC Server will pick up the message.
- Myapp will wait for the RPC Server to return the result before continuing with other processes.
- You usually use RPC calls if you need an immediate response. For example:
- You want to fetch user data from the database. You can't give any HTTP Response before you get the result from the database
- You want to update a product description. You can only return HTTP Response to the user once the process is completed (or failed).
The following are some feature flags to activate/deactivate the features:
- Frontend:
MYAPP_APP_ENABLE_FRONTEND=true
- API:
MYAPP_APP_ENABLE_API=true
- RPC Caller/Event Publisher: This feature is always activated
- Auth module:
- Auth API:
MYAPP_APP_ENABLE_AUTH_MODULE=true
MYAPP_APP_ENABLE_API=true
- Auth RPC Server:
MYAPP_APP_ENABLE_AUTH_MODULE=true
MYAPP_APP_ENABLE_RPC_SERVER=true
- Auth Event Handler:
MYAPP_APP_ENABLE_AUTH_MODULE=true
MYAPP_APP_ENABLE_EVENT_HANDLER=true
- Auth API:
- Log module:
- Log API:
MYAPP_APP_ENABLE_LOG_MODULE=true
MYAPP_APP_ENABLE_API=true
- Log RPC Server:
MYAPP_APP_ENABLE_LOG_MODULE=true
MYAPP_APP_ENABLE_RPC_SERVER=true
- Log Event Handler:
MYAPP_APP_ENABLE_LOG_MODULE=true
MYAPP_APP_ENABLE_EVENT_HANDLER=true
- Log API:
By activating/deactivating the feature flags, you can control Myapp's communication pattern. You can make it respond to all API requests, events, and RPC calls. Or you can make it respond to API requests but ignores RPC/Event calls.
Myapp will behave like a monolith if you activate all the features.
A Monolith handles everything. Compared to microservices, a monolith is easier to maintain/deploy.
If you only have a single developer team, a monolith is much preferable.
However, since everything run in a single application, a problem in any component can affect the whole system. For example, if your Auth RPC Server takes up a lot of CPU usage, you might not be able to handle the event log.
Scaling a monolith application might also be challenging. The easiest way to scale up a monolith application is by using a more resourceful (and expensive) server. This probably won't be a good idea if your application receives spike requests once in a while. You will have to pay for the highest capacity all the time.
You can spawn multiple Myapp, each with different configurations. By doing so, you can have a distributed architecture where some of your applications are deployed on cheaper Virtual Machines (like Spot Instances).
Furthermore, you can spawn more services if you encounter spiked requests. For example, there is a flash sale and you only need to spawn more services to handle sales orders. Once the flash sale ended, you can scale down your services.
Microservices are more difficult to deploy/maintain since you have multiple instances of your services.
You will likely need different teams to handle each service.
By using Zrb, you will be able to run Myapp as either a Monolith or Microservices. You don't need to set the feature flags manually.
# Run Myapp as a monolith
zrb project myapp monolith start
# Run Myapp as a monolith inside a container
zrb project myapp container monolith start
# Run Myapp as microservices
zrb project myapp microservices start
# Run Myapp as microservices inside containers
zrb project myapp container microservices start
# Deploy Myapp to Kubernetes as a monolith
zrb project myapp monolith deploy
# Deploy Myapp to Kubernetes as a microservices
zrb project myapp microservices deploy
Hopefully this will make your development/deployment process easier.
You can run your application as a monolith in your local computer, and deploy it as microservices later.