Letâs all agree on one thing: Writing backends is hard, and we suck at it.
Yeah, sure, weâre all great at creating our Express server, with our MongoDB or MySQL attached to it, but what comes after?
Are you sure that your dedicated server is ready for when your app starts being successful? Yeah, you could optimize your server, harden your Linux, remove unnecessary packages, stop services, etc. Still at some point, youâll need to scale up your server, buy a more expensive one. But what if that is needed for only that moment when a high influx of users come into your site? Do you downscale to keep your budgets down? Do you keep paying for the server? Have you even thought about adding a load balancer?
The solution is obvious: Serverless and the cloud!!!!1!one!
Sadly, this is not the reality. Why not? Because itâs just more stuff to learn, and itâs not like learning a new library/tool, itâs a ton of info. Have you considered your cloud already? AWS, Azure, Google Cloud Platform?
Letâs suppose you chose AWS, here are some more questions: Will you use DynamoDB? Or Aurora? Do you know how to query those databases? Are there any ORMs available for your language+database combination? Are you deploying all of this infrastructure manually? Or are you using something like Terraform or Serverless? By the way, how comfortable are you with YAML? :joy:
Not only that, now your code gets executed in separate functions. Donât try packaging your entire Express server into that. Well, at least if you value your wallet đ
Did you think already about the architecture for your app? Will you communicate the different parts of your app through a queue? Will you do direct calls? Are you gonna store stuff in the database directly? Or is it gonna act more as a cache? :thinking:
Also, remember that you have to create a proper SDK on the frontend to interact with your backend.
OH! I nearly forgot! Are you gonna add analytics to your app? Because itâd be good if you thought about that in this moment, where you can start gathering data right from day one.
And as a final note: Good luck maintaining it. đ
You might be one of those people who see the text above and think âAnd whatâs the issue with all of this? Itâs part of the journey, Iâm okay spending 95% of my time learning all this stuff and maintaining it, Iâm a developerâ.
Sorry, but in that case, youâre missing a lot of good stuff.
I think that we all agree that tinkering with pointers and registers is not something from nowadaysâ daily development scene. Sure, there is this small percentage of people that do this in order to optimize the speed of their system, but itâs not the vast majority of us. Why? Because of speed of development.
The usage of those things have been abstracted for us, so we write less code that doesnât matter, and write more of the code that matters: The one that makes our app different
Same stuff with fonts, you donât design a font each time for your application, but rather, you just choose the one that fits best for the use-case.
What if I told you that thereâs a way to abstract all of this hard stuff regarding to backend development, and just focus on what matters in that code that makes your app different?
Enter Booster framework
{% twitter 1281609074975690753 %}
Booster is this TypeScript framework distilled from years of experience working with companies like eBay, PayPal, Rent the Runway, or Zara. The folks at The Agile Monkeys got tired of reinventing the wheel constantly, and created the ultimate backend framework.
The premise is simple: Make developersâ lives easier.
So, what makes Booster special?
It:
- Requires no prior knowledge of backend development.
- Frees you from thinking about servers.
- Eliminates the need to configure your database.
- Avoids having to configure endpoints.
- Deploys to your favorite cloud, without having to read their docs thoroughly.
- Removes any costs for your deployed app while youâre not using it.
- Has built-in analytics data gathering for your app.
- Is extensible with plugins in case you really want to tweak something (we call these rockets).
Also, you donât have to be thinking in architectures, Booster has thought that already, extracted from the enterprise projects above and many others.
Ok, how does one use it?
Iâm not gonna get too deep into actual usage, because this is not a tutorial, but Iâll show you enough to see whatâs going on when you work with Booster.
When you use Booster, you interact a lot with the boost
CLI tool that comes with it. Booster has a tiny bit of boilerplate code, but you donât want to write even that one.
How does one configure their app? Thatâs the magic, you donât! The only thing you have to do is write your app around the following concepts:
Commands
A command is a class with some fields that represents an order to your system, along with a handle
method that will validate those fields, registering some events (we will talk about them in the next section). Examples of commands are generally the continuation of the sentence âA user canâŠâ, e.g.:
- A user can deposit money
- A user can send a message
- A user can create a chat room
How does a command look in practice? Just TypeScript code, and the best part, is that most of it is autogenerated! With a command like boost new:command DepositMoney --fields accountId:UUID amount:number
youâll get a file under src/commands
with the following contents:
@Command({
authorize: ...
})
export class DepositMoney {
constructor(
readonly accountId: UUID,
readonly amount: number
) {}
public async handle(register: Register): Promise<void> {
register.events(...)
}
}
You would now specify who can execute this command in the second line, write your validation code inside of the handle
method, and register the events. THATâS IT! No HTTP methods, no routing endpoints, deep controllers, or whatsoever, just the important code.
Events
Same as commands, eventsâ code is autogenerated with a command in your terminal, they are a regular TypeScript class as well.
Remember when I said that your app integrates already the data gathering for analytics? Itâs because of events! Instead of changing your database, performing queries, etc. You just represent that change as an event. Booster will store all these events infinitely, meaning that at any time, you can check what steps did a user do in order to trigger that bug, see if those users are dropping your registration process due to UX or a bug, think in how to optimize new features, and much more!
Examples of events are facts that you can state after a command, many of them are pretty obvious:
- Deposit performed
- Message sent
- Room created
(Note the ed
)
A newly created Booster event looks like this:
@Event
export class DepositPerformed {
public constructor(
readonly accountId: UUID,
readonly amount: number
) {}
public entityID(): UUID {
return this.accountId
}
}
Entities
Entities are the internal state of your application, but you donât modify it. Instead, Booster does something like an Array.reduce
to this infinite list of events that you have, to convert them into a tangible object. Entities have many uses, but the most important one is snapshotting, so your backend is FAST.
Examples of entities are concepts in your app, stuff like:
- Bank account
- Conversation
- ChatRoom
Hereâs an entity that calculates its balance
from the DepositPerformed
event, initializing balance
to 0
in the case that the account doesnât exist yet:
@Entity
export class BankAccount {
public constructor(
readonly id: UUID,
readonly balance: number
) {}
@Reduces(DepositPerformed)
public static reduceDepositPerformed(event: DepositPerformed, current?: BankAccount): BankAccount {
const currentBalance = current?.balance ?? 0 // ^-- Note how this is optional, because at the beginning of your app, the account doesnt exist
return new BankAccount(
currentBankAccount.id,
currentBalance + event.amount
)
}
}
Read Models
Read models are the way you expose your entities to the public. Read models act as a cache to make sure that your app gets the data ASAP. Also, they allow you to combine different entities, and transform the data in a way that it makes sense for your frontend. Again, a regular TypeScript class:
@ReadModel({
authorize: ...,
})
export class AccountReadModel {
public constructor(
public id: UUID,
readonly balanceMessage: string,
) {}
@Projects(BankAccount, 'id')
public static projectBankAccount(entity: BankAccount, current?: AccountReadModel): AccountReadModel {
let message = "Broke"
if (entity.balance > 1000) {
message = "Has sum money here, yo"
} else if (entity.balance > 10000) {
message = "Hey, this person is saving for sumthin'"
} else if (entity.balance > 100000) {
message = "Whoah, they gonna buy a house or what?"
} else if (entity.balance > 1000000) {
message = "They got a shit ton of money, yo!"
}
return new AccountReadModel(entity.id, message)
}
}
Thatâs it!
Now, to deploy this, you just write boost deploy -e production
.
AND THATâS IT. PERIOD.
No configuration, no control panels, no YAML, no anything! Just press one damn button, and you have your app deployed to the cloud
You get your cloud properly configured, with all security measures, architecture, interconnection of services, etc.
Booster spits out a URL which is a GraphQL endpoint for you, and thatâs it.
Right, but how do I connect this to my frontend?
Because it is GraphQL, you can perfectly use a library like Apollo in order to connect it.
Using React? Vue? Svelte? Elm? No problem, just use the Apollo adapter for one of those. No need to write SDKs/services for talking to the backend.
Commands can be executed through Mutations, Read Models can be queried or subscribed to. Thatâs it, no need to encode URLs, remember parameter orders, create API documentation with Swagger, etc. Just use what you coded.
This is too good to be true, it must cost a lot, right?
Nope, the framework is absolutely free to use and open source. If you are worried about the costs of the cloud, all Booster projects are eligible for the AWS free tier, and even without it, for 40.000 (thatâs forty thousand, btw) requests in one month, youâd pay less than one dollar.
(No, the team doesnât get any cut from cloud providers, we are just fed up with tools that create problems instead of solving them đ)
Ok, what to do now?
If you reached so far, congratulations, and thank you! Nowadays frameworks appear every day, and people just roll their eyes. Booster is truly different and groundbreaking. For learning more, checkout the projectâs website, where you can find links to documentation, demos, and much more.
I also recommend you to join the projectâs Discord server and challenge it with your ideas, thoughts, and questions. A project is nothing if it stays in the same place, and by challenging it, you are already helping!
Booster is also part of Hacktoberfest, in case you want to contribute wink wink; nudge nudge. And even if not, a star in our GitHub repo would mean a lot.
Stay tuned for more!
May your day be awesome, and your backends easy đ, Nick