The moclojer is an Open Source product. To serve it as a service, we created an event-based architecture for event propagation and data processing, generating triggers for specific actions.
The following are the services and integrations that keep moclojer’s backend alive:
unified mock
, aggregating all user mocks for use in moclojer-foss
’s runtime. Generated files are stored in our object-store
;unified mock
given from consequent events from yaml/generator
, serves unique mock endpoints, acting therefore as the final API.We serve a web interface for user interactions. This interface is responsible for interacting with our Backend Services and deliver updates to our user.
We use DigitalOcean as our infrastructure provider, our goal is to serve moclojer foss in a scalable way for all users. To achieve this, we use the App Platform to serve applications, Managed Database to provide managed databases (PostgreSQL and Redis), and Droplet to serve the reverse proxy and Supabase for frontend authentication.
Application logs are sent to Logtail, installed via DigitalOcean add-ons.
The App Platform is a platform as a service (PaaS) that enables developers to build, deploy, and scale applications quickly and easily. It supports several programming languages, including Clojure 💜, and provides a range of features to help developers build and deploy applications more efficiently.
We have two applications on the App Platform:
moclojer-app
static_sites
serving the frontend, with ingress
(public access)services
serving the back/api, with ingress
(public access)workers
running the yaml/generator and cloud/opsdatabases
running the postgres and redis/mq managedmoclojer-foss
services
serving the moclojer/foss, with ingress
(public access) - with support for multiple domainsWe use managed infrastructure to focus our efforts on the product we serve as a service, not on the infrastructure that supports it. DigitalOcean helps us stay focused on what really matters.
This is a simplified overview of how our described services connect and interact between themselves after built, deployed and running on Digital Ocean.
graph TD; subgraph "DigitalOcean" subgraph "database services" postgres redis/mq end subgraph "App Platform" back/api frontend cloud/ops yaml/generator moclojer/foss end subgraph "Droplet" p001/proxy end paas-service object-store end back/api --> postgres; back/api --> redis/mq; back/api --> object-store; frontend --> back/api; frontend --> supabase/auth; cloud/ops --> redis/mq; cloud/ops --> p001/proxy --> dns-services; cloud/ops --> paas-service; yaml/generator --> object-store; moclojer/foss --> object-store;
This is an overview of how an optimistic run of the use case of a mock creation gets our services to work together.
sequenceDiagram; participant frontend; participant back/api; participant db; participant yaml/gen; participant cloud/ops; box cloud providers participant cloudflare; participant digitalocean; end frontend ->>+ back/api: post /mocks; back/api ->>+ db: insert mock; db ->>- back/api: ok; back/api -->> yaml/gen: generate mock file; back/api ->>- frontend: 200 ok; loop mock offline frontend ->>+ back/api: get /mocks/123/publication; back/api ->>+ db: select mock publication status; db ->>- back/api: ok; end yaml/gen -->> yaml/gen: generated unified mock file; yaml/gen -->> cloud/ops: create domain; cloud/ops ->>+ cloudflare: create DNS record; cloudflare ->>- cloud/ops: 200 ok; cloud/ops ->>+ digitalocean: create domain; digitalocean ->>- cloud/ops: 200 ok; cloud/ops ->> back/api: mock published; back/api ->>+ db: update mock published; db ->>- back/api: ok
As previously mentioned, we use Redis MQ to facilitate communication between services via Redis’s Pub/Sub capabilities. Our queues are, separated by service, specifically:
mock/api
domain.verify
;unified.verify
;yaml/generator
object-store
, and packaged to be unified;unified mock
, used thereafter by moclojer/foss
;object-store
and signals the recreation of the global unified mock
;unified mock
, signaling the recreation if not;cloud/ops
mock.publication
thereafter;moclojer/foss
unified mock
, restarting the running moclojer server instance;