Microservices
Communication between services
- Sync: direct requests
- Plain http requests with json exchange format
- Can create a big web of dependencies between services
- Async: communication using events
- Services emit and receive events to/from a Event Bus
- Has data duplication!
- The Query Service is responsible for the Event Bus (Event Broker)
Error handling middleware
- A function to handle all
throw new Error('')
along the code - A class is created for each error type and extends the 'Error' class
- Error structure:
{
"errors": [
{
"message": "Database error",
"field": "field"
},
{
"message": "Validation error"
}
]
}
export abstract class CustomError extends Error {
abstract statusCode: number;
constructor() {
super(); // Invoke the constructor of the Error class
Object.setPrototypeOf(this, CustomError.prototype); // setPrototypeOf must be called when extending a built in class
}
abstract serializeErrors(): { message: string; field?: string }[];
}
Authentication strategies
-
Tokens: JWT, Cookie, etc
-
Option 1:
-
"order" service always ask "auth" service
- "auth" service checks if the token is valid and the user is authenticated
-
"auth" sends the response back to "order" directly (not through event bus
-
Option 2:
-
"order" has all the logic to validate a token
- "order" doesn't need to reach auth service
- user could be banned and the auth service could not tell the order
-
A "ban event" could also be emitted b the auth service
-
JWT
-
Request: Authorization (header), token (body), Cookie (header)
- A payload is transformed in a jwt string by means of a secret key
-
the jwt is decoded by the server
-
Cookie
- Request: Cookie: 'blabla'
- Response: Set-Cookie: 'blabla'
- Server emitts a Set-Cookie and the Client stores it in the browser
- The Cookie is sent back by the Client when it makes a new request
Server-side render
- Browser make request to an back-end server (NextJS)
- NextJS build the html for the entire app by requesting other services
- NextJS sends back to browser fully rendered pure HTML
- Boost the page load speed
- With server-side rendering, NextJS must know auth info with the first request
- Auth info MUST be passed as a Cookie (with jwt inside) with server-side rendering
Cross Service data replication
Embedding strategy
- Strategy to associate a internal model to another external model from another service
- A property of the internal model receives a whole document of the external model
Ref/Population Feature
- Populates an external model to inside of a property
- Two separate collections
Optimistic Concurrency Control
- Add a version to any document in the database
- Each update will be made considering the previous version
- If the version is not the desired, the update will hang
- 'mongoose-update-if-current' module
- The version number should only be incremented in the service that primarily stores it
Scheduled event
- The event will only be redistributed by the event bus after some time window
- Not supported by nats
- BullJS library handles timing notifications
Worker server
- A independent standalone service that process demanding actions
- Example: a video file conversion is process demanding and takes time
- That way, the original service is free to perform other activities
- A
Job
is the unit for the action to be processed by the worker BullJS
handles the jobs in the worker
Payment handling
- Stripe handle credit card payment
- A token is created and with that the payment is sent to stripe API
- default test token
tok_visa
Hosting providers
- Digital Ocean
- AWS
- Google Cloud
- Azure
Further development
- HTTPS support
- cert-manager.io
- Email support
- Mailchimp/Sendgrid
- Production dockerfile and K8S config files
- Production files adding the build step
- Staging cluster
- Cluster for testing on Digital Ocean