Codenames better recognize how design evolves over time.
* If you split functionality out of one service, you end up with the old service's name implying it does both. E.g. you end up with a "auth" service that only handles cookie auth but not API keys.
* If you expand the functionality of a service, you end up with a service's name not really clueing you in to what it does. E.g. "metadata" service that actually now includes smaller objects inlined into the database.
* When you make a rewrite of a service, until the old one is fully retired you have two confusing names, and I hope you don't pick "new_auth" or something as that will be even more confusing after the first is turned down.
Also codenames make searching for a particular component really easy. If you have to search for "auth" you will get all kinds of irrelevant results. If you search for "kazoo", you'll probably only get docs related to kazoo!
> If you split functionality out of one service, you end up with the old service's name implying it does both.
If you change what a class does you need to change the name, if you change what a method does you need to change the name, same for services. If it's too hard to change service names, that's your problem.
> When you make a rewrite...
Internal changes in a service must be transparent to consumers. If consumers are aware that you are doing internal work then you are doing something wrong.
Codenames is the equivalent to call your variable John.
This completely fails to recognize the cost of change at different layers of abstraction. A service is an external facing entity that other teams need to interface with, it would cause an insane amount of churn to try to make changing service names as easy as changing internal class names, let alone local variables.
> it would cause an insane amount of churn to try to make changing service names as easy as changing internal class names
It's easier to change your service name that a class name or method in a popular library used by millions of developers, and it is done because it's the only thing that makes sense.
Can you imagine that your framework class to store data was named "Mercury" and the one to manage HTTP connections "Saturn"? Nobody would use such a thing.
Good descriptive names help to use software properly. If you cannot change a service name because it's too costly, review your development process.
I really like the comparison to variables/classes because it shows how poorly descriptive service names work. Services contain hundreds to millions of variables, classes, and lots of features, layers, etc. Comparing a service name to a variable shows why it's a poor idea to try to name your service descriptively, it contains so much and will change over time. And refactoring classes is easy, renaming services is much harder.
> Codenames is the equivalent to call your variable John.
Imagine that you have a singleton object floating around your system, every single function written anywhere in the system must interact with that object heavily, and as a consequence everyone is familiar with what the object does and where it's defined.
What problems do you think might arise if that object were named "John"?
That each new developer needs to learn that name. That it's difficult to understand what is that variable scope: does this new functionality fit in John or not. That most people know John but what happens with that other one that is rarely used named Jack and you find in in the code, and Anna and Maria?
It would be the same for the computer running the code, the problem is for the developers trying to understand how to use it, how to expand it, etc.
Totally agree. Haven't heard someone describe this way of naming as "codenames", which I think gives the right impression that's is a placeholder name. It also suggests the service is a proper noun, instead using a name like "shipments" which is actually pretty confusing, since you often have to determine if you mean actual shipments or the service based on context.
My experience is when we use "trivial" names folks just use abbreviations or other methods to disambiguate them anyway. For example, look at all the AWS services. Does anyone ever say "Elastic Compute Cloud" service? Come to think of it, that does seem like a fair compromise to have some formal-ish name for the service and just use a codename when referring to it.
> Haven't heard someone describe this way of naming as "codenames", which I think gives the right impression that's is a placeholder name.
"Codenames" are used for products for which the "name" is recognized as significant to the product. Thus, choosing the name is a project of its own -- and might take quite a bit of time -- while you might want to start work on the product before you finish picking the name. (Indeed, the work might inform the name!) But you have to be able to refer to the product, so you just give it some other name. When it's ready, you give it the "name".
That's not what's happening here; what we have here is a big complicated system with a name. We don't expect to replace the name, but we do need to have it so that we can talk about the system.
That service name is in docs, channels, conversations, and in people's heads as well. Renaming services introduces a lot of confusion that extends much longer than the amount of time it takes to change the written references.
When you split out part of a service, every previous reference to that service is now potentially wrong, because it may refer to the part of the service which have been split out. So explicitly breaking them is possibly more useful than preserving them. The crucial thing is to maintain a history of the names - precisely, a phylogeny of services.
I guess it depends on the tech stack. Where I work it's very difficult, and I've never seen it happen. We have 10 year old obsolete names appear regularly.
I think the "what a service does over time evolves" is probably the best argument I hear, but for me it comes down to a numbers game. Especially with microservices the majority of them don't evolve. So it becomes a question of which is preferable
1. 10 services named after Darkwing Duck characters
2. 8 services with descriptive names, and 2 with slightly wrong names
AirBnB doesn't allow you to name microservices descriptively. It makes sense because it doesn't scale. After the 10th "SMS Service" is created, no one knows what any of them do. And that's kind of the point of microservices, you have lots of them. It's inevitable there will be overlapping functionality.
There's plenty of other reasons too.
Silly names are fine, it takes just as much time to learn what "Ernest" does as it takes to learn what "shipping" does. For both services, there's 30 seconds of learning, and then everyone knows what both names mean.
After the 10th sms service I'd be curious to know why people have done the same thing ten times. If there is a real difference in functionality between those ten services, I suppose the next question is why don't their names reflect that?
One of the useful things about descriptive names is that it can help you detect duplicate work.
First, the same problem applies to service names like "Galactus" or "Buttforce". Second, a descriptive name is not the same thing as a service description. A descriptive name or label is as much a mnemonic device as is is a name. They're intended to be easier to remember, not to replace proper documentation. Third, just from the names it looks like Text Service is the front end for an ecosystem of texting related services, reach of which is implemented using a different technology. Though twilio and telephony look like especially bad names for services behind a texting service.
> After the 10th "SMS Service" is created, no one knows what any of them do
Yeah, that's always been my concern. "Descriptive" is a very precarious strategy because it takes very little to go from maybe descriptive to generic and confusing. Multiple variations of the same "descriptive" name are another common issue. I see often a lot of very similar named services that are the bane of naming in my opinion. Someone made a User Management Layer and then someone else made a Person Data Service and next thing you know you see a User Data Service and now it's just confusing. Factor in that each one of those things gets called the UML, PDS, and UDS and it just gets worse (did I mention they each connect to the Person/User Data Store/base).
> it takes just as much time to learn what "Ernest" does as it takes to learn what "shipping" does.
If that is right we should apply it everywhere, as it does not matter. My method many is going to be PeterPan and the class name Wonderland. It's as easy to learn as a descriptive name.
Are you also going to create 10 classes with incompatible but overlapping interfaces and tradeoffs?
Some names are descriptive and other are just names. Your coworker is more likely to be named Ernest than GuyWithLongHairThatListenToPopMusicWhileReadingMangaAtTheParkAndIsReallyGoodWithPython and that is probably a good thing.
And there are five Ernest and twelve Daniel, maybe we should name most classes the same also. When compiling the code a prompt may ask what Ernest do you mean.
At the beginning of my career I always choose fun names and was strongly in the camp of having fun names to identify better with my projects.
After a few years, a growing number of services and branching out a bit more into infrastructure I came to the realization that this isn't the best choice and I'm fully in support of boring descriptive names now.
Our services are now called scraper, proxy-manager, webrouter. This makes it a lot easier to see dependencies, figure out what an alert is for or track down issues in a large micro-service architecture where you are not always sure what a service is used for.
After a few more years where you have to scale these systems and redesign what services do and create competing ones that exist in parallel, you may find yourself back in support of non-descriptive names.
Maybe, except there's not much downside. You also save significant time, because engineers trying to come up with the name of a service can be a drawn out and painful exercise, especially if it's a new service where you won't know its full responsibilities and boundaries until it's been used and built on for a significant time in production. I've seen so much time wasted with engineers trying to name services descriptively, especially when a similar service already exists.
Personally I think I would go with a identity vs function distinction: a cog in an engine does not need a unique name, the entire car can benefit from one.
The name is an abstraction. Naming it "cache" is not specific enough.
The uses and functionality of services change over time and then you have to rename them.
We have a service called "Search" that does... much much more than search. If we had named it "Harry" we could put a README in the project root and avoid confusion.
In fact, looking around my current work's stack... we have a LOT of "boring" service names that no longer describe what the service actually does.
If a search service does more than search, this is a problem to be solved, not a property to be accommodated in a naming scheme. One of the core purposes of a service oriented architecture is to define and enforce bounded contexts. Purpose-driven names reinforce that goal.
DDD is a poison to the mind and business growth. Keep the domain at the user configuration level where possible, not locked in to service design. Build domain agnostic, functionality based services. You shouldn't need to channel engineering to iterate on your business model. In the context of naming services it's even worse, trying to name services after significant domains in your business is an even stronger lock-in of temporary business concepts to service design. It's a poisonous coupling.
This article is too long for the simple point it makes. “Don’t name your service fun cryptic names because it doesn’t scale well” could have been a paragraph on why it’s bad.
I was hoping for a framework on naming services/APIs when a good technical name is not obvious. How do I know if “fee-record-srv” is a good or bad name? What do I do if my service’s responsibility changes over time, etc.
The fact that this is such a common phenomenon supports the argument that programming is pop culture, and it validates the complaints of so many of us curmudgeons.
I think you can forgive people for naming things abstractly because they don’t want to shoehorn them into a specific purpose. Calling your company’s app something vague like Fulgur rather than API makes it so you can avoid the “yes we know it’s called API but due to historical reasons it also handles some batch processing.”
110% this, especially as a security engineer who might have to know about all the microservices in a product, while the software engineers might only have to know about a few of them.
It's especially bad when there's a major lack of documentation, so I gotta either set up tons of meetings or spend time examining code just to figure out what Galactus, Omega Star, and Papaya all do.
> It's especially bad when there's a major lack of documentation, so I gotta either set up tons of meetings or spend time examining code just to figure out what Galactus, Omega Star, and Papaya all do.
But you have to do that anyway. If you don't bother examining a service's most-commonly-used functionality just because the service's name implies different functionality, what kind of security engineer are you?
I like codenames that have some sort of a association with the thing being named, like “igor” for the service that retrieves something, or “hoard” for the service that stores something, or whatever. Because the association helps you remember, but it’s also is loose enough to allow for things to evolve and responsibilities to be split in the future.
This requires everyone else who works on your product to be embedded in and cognizant of the same pop culture as you.
Sorry, engineers who grew up in another country. Sorry, offshore QA team is going to be utterly baffled by your nomenclature. Sorry, college grad new hires.
My favorite part of this video is how it accidentally shows the benefits of silly names: "Bingo knows everyone's name-o" is clever and easy to understand what it does. If this was called the "name service" no one would have any idea what it did from the service name alone. You have to learn what both services do regardless of descriptive or silly name, and Bingo is arguably easier to remember.
Naming your microservice after a favorite pop culture entity may end up spoiling your enjoyment of said entity, because the name will trigger PTSD from that messed-up microservice. So better pick some neutral name.
Yeah, but if you have shipping01...03 instead of quirky-noun, ugly-color, and random-animal, then everybody will just know what's broken straight away and you won't have a job
Besides, half of the fun is in figuring out who (or what!) deployed the mystery service, as well as the secrets that lie within (and are not in the password manager for some reason, Carrrl)
Suddenly lamenting the emptiness left by the lack of configurability for those name generators, a la i18n.
"Pop-culturation, or p13n, helps teams reduce the randomness of their random names by seeding the noun/adjective list with configurable themes, like old-timey western european guys in wigs, famous rapppers, characters from The Office, Seinfeld, Pokemon, and more. In this repo, I will..."
This doesn’t work once you are big enough or have been around long enough that a service needs to be rewritten. Personally I’m a proponent of <code name>_<functional name>. Descriptive names with the ability to disambiguate.
I've seen codenames in modern microservices and in very old systems where the operating system's file names limited creativity for binary names to two-letter area code and 6-digit running number for a module of the system. Fun times!
Codenames pros & cons
---
Pros:
- security by obscurity – you won't understand your system beyond 20+ services; the attacker also :)
- no discussions in the team on naming the service – you just take the next name from the list from the dictionary you chose
- service splits or merges don't change the service name
- ownership changes and moving services to another domain does not affect the service name (it may make it sound like from another universe though, like a black sheep, e.g. mixing chemical elements with action figures)
- does not lead to acronym invasion where three three-letter acronyms describe three different services and you never know which is meant
- leads to stronger ownership for the service
---
Cons:
- no way to understand what the service does w/o looking at API spec or one-line description (which does not exist)
- multiple teams will implement (almost) the same thing and won't run into a naming collision telling them otherwise
- optimizes for # services built, not well-defined domain/product structure
- service splits or merges may invalidate the former name causing you to rethink the implications for your customers and those you know what X does
- with sufficient amount of teams you will run into name collisions anyways as you run out of hero names, chemical elements, action figures, etc.
- cross-team communication is very hard as teams speak gibberish to one another – it's like you'd read: "'foo' failed because of timeouts from 'bar' causing resource exhaustion and thus circuit breakers opening in 'handy' and 'dandy'"
- English words will mix with service names making communication hard to understand as you won't be able to tell from context whether it's a service name or word
- if you use codenames for teams you will run into the service name & team name collision eventually
- strong ownership for the service leads to dysfunctions where devs get too opinionated and clingy to their past decisions
---
Ways to organize the codename mess:
- Use functional DNS names to alias the service URLs (you can change the implementation, but keep a stable interface for clients)
- Use functional names in cross-team communication, but codenames internally
- Market under the codename, so that the name is catchy
- Application registry (API/CLI) allowing to view metadata & one-line purpose of the service
The argument for descriptive naming is that you want to make it easier for people that lack an understanding of your architecture to make changes to it?
* If you split functionality out of one service, you end up with the old service's name implying it does both. E.g. you end up with a "auth" service that only handles cookie auth but not API keys.
* If you expand the functionality of a service, you end up with a service's name not really clueing you in to what it does. E.g. "metadata" service that actually now includes smaller objects inlined into the database.
* When you make a rewrite of a service, until the old one is fully retired you have two confusing names, and I hope you don't pick "new_auth" or something as that will be even more confusing after the first is turned down.
Also codenames make searching for a particular component really easy. If you have to search for "auth" you will get all kinds of irrelevant results. If you search for "kazoo", you'll probably only get docs related to kazoo!