Today’s random F# code: Code Structure

A frequent question I get is how to structure a codebase in F#. There is not much about this topic out there on the Internet. So here is how we structure our code:

The above snippet from our solution shows a single sub-system. Our application, an attendance tracking system, is split into several sub-systems: attendance time, employment (everything about employees), organisation (who works where in which role), absence planning (like vacation, or being sick), duty planning, activity time (e.g. booking time on projects), expenses, tool usages, and a couple more.

Each slice follows roughly the same layered structure:

  • API: provides end-points for the clients to call
  • Facade: provides an interface of the core business functionality to call it from the API or our tests. We distinguish between calls coming from the API (OrganisationFeatures) and calls coming from other sub-systems (AdapterFacade).
  • Features: the commands and queries that the sub-system provides
  • Core domain: models and business logic that enable the features

Because F# uses strict ordering of files and definitions in these files – you can only use what was defined above – the order of the files in the snippet is reversed to the list.

Feedback

Does a each subsystem map to an independently deployable unit? Or all sub system are bundled into a monolith?

Karim

All sub-units are deployed together to Azure-WebApps and -Functions. We see no benefit in individual deployment at the moment because we are a single team, and the deployment takes 30 seconds with zero downtime. The coupling due to how our business works, is high as well.

We have a mixed codebase (F# and C#), so the composition is a bit of a wild mix of both. That’s why I don’t want to show it. But my mate @domhelfenstein has made a small sample of how we would probably do it https://github.com/domenichelfenstein/bike-rental-showcase/tree/master…
Composition Root: bike-rental-showcase/FacadesCreator.fs at master · domenichelfenstein/bike-rental-showcase · GitHub

Any good reason to why you have separate projects and not just two projects, one for app and one for testing?

Tomas Jansson

Core assemblies have fewer assembly/Nuget package dependencies, which results in faster compile time. Most tests run against code in Core assemblies. So the TDD cycle is faster because the build takes less time.

About the author

Urs Enzler

Add comment

By Urs Enzler

Recent Posts