Domain driven design (DDD) blog in Typescript with Adonis

ivanprats.dev Blog using DDD

This is the code that powers the ivanprats.dev website. What you are reading right now is in fact the README.md of the public code repository.

It mainly follows the practises from Domain Driven Design (DDD from now on) with Hexagonal Architecture / Ports and Adapters Architecture (HA from now on).

It's written in Typescript because:

  • it's typed and I-love-me some types (eventhough it does not offer a hard typing check at runtime)
  • I like it and it's my personal website

But for a blog I could have chosen to do it in virtually any language I wanted to.

I'm using Adonis.js because it offers a good amount of packages that do all the boring stuff in a web framework: starting the server, handling requests, routing, Typescript processing, serving assets... But, if you are familiar with DDD / HA, most of the Adonis.js packages and code will be contained in the Infrastructure layer (like it should be). Leaving all the core (domain layer) code in pure Typescript.

This blogpost is a work in progress, I will add to it everytime I add new stuff to my personal site.

Introduction & Disclaimer

I personlly think that using DDD + Hexagonal Architecture to power a blog is the definition of overkill.

A simple Ruby on Rails, or static site would have been more than enough. In fact a static site would have been cheaper to maintain, and easier to scale in terms of website users.

But I still chose to do it like this for the following reasons:

  • I use my personal site to play with new techniques and technologies
  • Because there is no business incentive to my blog: I can open-source it and show it around so that colleagues, future employers, customers... so they can see it and we can discuss it

Interesting stuff to check out in the codebase

If you are not familiar with Adonis: you may not know where to start, so here I will point out to the most interesting (in my opinion) parts of the code base. As well as quickly introducing what they do. Some of them will be further explained below

  • Testing. All tests are in the root tests/ folder. They are separated between Unit, Integration, and Functional tests. Unit tests are fast because they use test doubles to abstract fromm the Infrastructure layout. The Integration test that same infrastructure layout. And System tests are mostly Acceptance tests that ensure the system is working correctly from the Client's perspective. You can run them on your machine with the command node ace test

  • Easily using multiple types of "Databases" thanks to Hexagonal Architecture (HA). I say "Databases" with quotes because you could hardly call storing blogposts on markdown in the repository a Database, but I still use it like one nonetheless. And that is precisely what I find incredible about HA: you can literally use whathever you want as long as Repository you are using follows the ProjectsRepository interface determined in your domain.