In the last part of our naming series (Naming things, part 3) I have layed out the schema for how we want to name our services.
However, after using this schema for a few weeks we found out that it actually doesn’t fit our needs as good as we thought. So we made some corrections.
Just as a small reminder, this was the way we defined the canonical name of a service:
So a webservice within the case system that is responsible for indexing cases into some sort of storage would have to be named something like:
When looking at a list of services however we’re primarily interested in the system in which the service is residing, then how the service achieves that goal (which is signalized by the type) and finally about what the services main responsibility is (which is communicated via the name).
So the actual composition of the canonical service name should be this:
This will rename our example from above to:
On the one hand this created quite a bit of work for us as we had to rename a bunch of repositories, change the application URLs and adjust build scripts and documentation.
But we think it’s better to invest that work now and in the future have a service name that really helps us in getting a better overview. Things change - and that’s just one of the things that changed for us.
So let’s take a look at our new service naming convention:
A service in the scope of this document refers to a single application following the microservice architecture.
A project in the scope of this document refers to an entity that uses a service or provides resources that are considered parts of the service during the development phase.
Examples for a project related to a service are:
- A GitHub project for a specific service represents the source code repository in which all artifacts for a specific service are stored.
- A CircleCI project for a specific service represents one or more buildjobs that are used to convert the service’s source code into an executable binary.
- A Heroku project for a specific service represents a hosting environment in which the binaries of a service are run.
Canonical service name
The name of a service is composed of three separate parts: The system, the service itself and the type.
The system describes the overall domain area in which the service operates.
The name of a system should always be singular (we speak of the
case system and not of the
The following systems have been identified so far:
||Manages a case throughout its lifecycle|
||Sort of “meta system” that is used to manage information about and from other systems (like collecting errors for analysis by the development team).|
||Manages the data for patients.|
||Manages the creation and processing of surveys that are being sent to patients to collect data.|
The type describes a high level idea of what the services main characteristic is.
There is a finite set of types that we currently use:
A container service is designed to deliver HTML fragments that are composed into an HTML document by Stacker which is our internal service that composes an HTML document from multiple sources.
A container service is always a web application and therefore exposes an HTTP port for a client (e.g. Stacker) to request and consume data.
A container service is identified by the type
A web service is designed to deliver HTML content and/or provide REST APIs that can be consumed by a browser and/or other clients relying on this data.
The difference between a web service and a container service is that a container service is specifically designed to be consumed by Stacker while a web service is specifically designed to be consumed by an external client (a browser and/or a REST client).
A web service is always a web application and therefore exposes an HTTP port for a client to request and consume data.
A web service is identified by the type
Note that even a service that at first glance doesn’t need to expose an HTTP endpoint as an API is a web service in our naming structure. There should be “meta endpoints” for monitoring which will make the service a web service.
A resource is a service that is not directly created and developed by the BetterDoc development team but “only” added into the service landscape.
Examples for a resource are databases, search indices or queues.
A resource is identified by the type
A development helper is any kind of application that is not directly linked to a running application that is accessed by a user.
It is designed to ease the overall development process for example providing a way to easily create a set of test data.
A development helper should never be accessed from any other type of service.
A development helper is identified by the type
The service itself is named after the actual responsibility.
Putting everything together
The complete name of service consists of these three components: The system, the type and the service itself.
The components are joined by a hyphen character (
-) using the following scheme:
We call this the canonical service name.
|Canonical service name||Description|
||A container service (
||A web service (
||A web service (
||A development helper (
Associated project naming conventions
The name of a service should always be used as base (or if possible exactly) for any project naming in external systems.
The following projects describe the naming convention for our regular projects
The name of the GitHub repository uses the exact name of a service within our GitHub organization.
|Canonical service name||GitHub repository name|
The name of a CircleCI project is always taken from the name of the GitHub repository for which a CircleCI workflow is generated. This means that the name of a CircleCI project is always the canonicasl name of the service within our GitHub organization on CircleCI.
|Canonical service name||CircleCI repository name|
As we can have multiple deployment environments for each service (e.g. testing, staging and production) the canonical service name is not enugh to uniquely identify a deployment environment for Heroku.
All Heroku apps therefore need to have an additional prefix to signalize the deployment environment.
|Deployment environment prefix||Comment|
Add-ons as resources
If an add-on cannot be added directly connected to a Heroku app (because it’s not possible or isn’t desired in a specific scenario) then a separate App should be created that doesn’t contain any dynos but simply has one or more add-ons connected to it.
This app then needs to use the
res service type.
|Canonical service name||Environment||Heroku app name||Comment|
||A database that is designed to store information about cases within the overall context of the
Heroku provides two general types of dynos:
The main difference is that
web dynos will be made available to users as HTTP endpoints, while
worker dynos will not.
So for each of our service types the following dyno type should be used:
|Service type||Dyno type||Comment|
|Container service (
|Web service (
|Development helper (
||Depending on the actual responsibility of the helper.|