At BetterDoc we’re currently in the process of step by step replacing an old monolithic application with a microservice landscape. While adding services whe recognized that we needed to find a consistent pattern to naming these services to keep the “service zoo” organized.
This post describes our overall scheme for naming our services.
Note that since writing this blog post our idea of how a service should be named has changed and the following rules are no longer valid. Our most recent thoughts can be found here: (Naming things, part 3B).
Definitions
Service
A service in the scope of this document refers to a single application following the microservice architecture.
Project
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 type, the system and the service itself.
Type
The type describes a high level idea of what the service main characteristic is.
There is a finite set of types that we currently use:
Container service
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 cs
.
Web service
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 ws
.
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.
Resource
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 res
.
Development helpers
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 dev
.
System
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 cases
system).
The following systems have been identified so far:
System | Description |
---|---|
case |
Manages a case throughout its lifecycle |
internal |
Sort of “meta system” that is used to manage information about and from other systems (like collecting errors for analysis by the development team). |
survey |
Manages the creation and processing of surveys that are being sent to patients to collect data. |
Service
The service itself is named after the actual responsibility.
Putting everything together
The complete name of service consists of these three components: The type, the system and the service itself.
The components are joined by a hyphen character (-
) using the following scheme:
<TYPE>-<SYSTEM>-<SERVICENAME>
We call this the canonical service name.
Examples
Canonical service name | Description |
---|---|
cs-case-phasecomputer |
A container service (cs ) which is part of the case system (case ) that is responsible for computing the name of the phase a case is currently in (phasecomputer ). |
ws-survey-surveymonkeyimporter |
A web service (ws ) which is part of the survey system (survey ) that is responsible for importing new data from Surveymonkey (surveymonkeyimporter ). |
ws-website-server |
A web service (ws ) which is part of the website system (website ) that is responsible for publishing the website to external clients (server ). |
dev-website-photocompressor |
A development helper (dev ) which is part of the website system (website ) that is responsible for taking photos and compressing them into a format that is small enough to be included on a website (photocompressor ). |
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
GitHub
The name of the GitHub repository uses the exact name of a service within our GitHub organization.
Examples
Canonical service name | GitHub repository name |
---|---|
cs-case-phasecomputer |
cs-case-phasecomputer |
ws-survey-surveymonkeyimporter |
ws-survey-surveymonkeyimporter |
CircleCI
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.
Examples
Canonical service name | CircleCI repository name |
---|---|
cs-case-phasecomputer |
cs-case-phasecomputer |
ws-survey-surveymonkeyimporter |
ws-survey-surveymonkeyimporter |
Heroku
App names
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 |
---|---|
t- |
Test environment |
p- |
Production environment |
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.
Examples
Canonical service name | Environment | Heroku app name | Comment |
---|---|---|---|
cs-case-phasecomputer |
Test | t-cs-case-phasecomputer |
|
cs-case-phasecomputer |
Production | p-cs-case-phasecomputer |
|
res-case-database |
Test | t-res-case-database |
A database that is designed to store information about cases within the overall context of the case system |
Dyno types
Heroku provides two general types of dynos: web
and worker
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 (cs ) |
web |
|
Web service (ws ) |
web |
|
Development helper (dev ) |
worker or web |
Depending on the actual responsibility of the helper. |