Rename Operation

Updated: Published: EuroPLoP 2024

Context and Motivation

An API endpoint, for instance, an HTTP resource, has been developed, tested, and deployed. The name of one of the operations of the endpoint does not represent its semantics well; there is a mismatch between the operation name and the performed operation. It is not easy to comprehend.

As an API provider, I want to express the responsibilities of an operation in its name so that client developers, API developers, operators, and non-technical stakeholders such as end users and product managers understand the API — and each other in conversations about the API.

Stakeholder Concerns

#maintainability
APIs should be changed as much as required and as little as possible, and ripple effects be avoided; source code and documentation on client and provider side using a particular name have to be updated if this name changes. Expressive operation names help with orientation during API evolution. Debugging and trouble shooting is also easier if logs and error reports contain meaninfgul names.
#understandability (incl. #explainability, #learnability)
All stakeholders involved in development and operations should be able to grasp what an API is supposed to do (and actually does) with ease; it should be straightforward to teach API usage. On the contrary, educated guesses and implicit assumptions are likely to cause misunderstandings that lead to technical risk and defects later on.

Initial Position Sketch

This refactoring deals with a single operation.

This is a rather trivial initial design to be improved with this refactoring, specified in the Microservice Domain-Specific Language (MDSL) notation:

endpoint type GenericEndpointOfUnknownRole
exposes 
  operation hardToGraspName 
    expecting payload "SomeRequestMessage" 

It is unlikely that an identifier such as hardToGraspName is part of the vocabulary of any application domain or genre that the API deals with (such as finance, e-commerce/retail, or distributed control system in a factory).

Design Smells

Curse of knowledge
The operation name is easy to comprehend – but only for the developers of the API implementation on the provider side. On the contrary, client developers miss required context information.1
Role and/or responsibility diffusion
The operation is doing something, but the effects of the operation execution are not clear. For instance, it is not specified whether it reads and/or writes provider-side data and application state. The domain model abstractions/concepts that it works with remain fuzzy. Precision might be harmed and ambiguities introduced.
Ill-motivated naming conventions
Knowing what no one else knows could be seen as a pragmatic approach to job security; obscuring operation names might be part of such a strategy. However, the attitude driving such naming decisions can be considered unprofessional or unethical [Zimmermann, Stocker, and Kapferer 2024]; API design and documentation should be seen as a service provided to the client community (and other stakeholders).
Sloppy naming
Another example of good intentions gone wrong is trying to be funny when naming program(ming) artifacts; endpoint and operation names are not the most suited places for humor or irony because they distract from the facts.
Cryptic or misleading name
The name of the operation is not only difficult to understand but also misleading. It might suggest that the operation does something that it does not, which may have been caused by a change in the implementation of the operation without updating the name.

Instructions

  1. Rename the operation in the abstract API contract and any technical API Description (for instance, its OpenAPI description).
  2. Refactor on the code level; for instance, apply “Rename Element” or “Rename Method” as offered by many Java IDEs. Optionally, implement a new stub that merely redirects clients to the new endpoint operation; in HTTP, this can be achieved with URL redirection and status code 301 [Fielding and Reschke 2014].
  3. Adjust the test cases and run them (to keep the builds “green”).
  4. Update all supporting documentation such as API reference and guides, examples, and tutorials. Check and update security rules if necessary.
  5. Inform all known API clients about the change, ideally with detailed instructions how to migrate. Code snippets that can be copy-pasted easily will be appreciated by the client maintainers.

Target Solution Sketch (Evolution Outline)

The following MDSL sketch outlines how to improve the naming on an abstract, conceptual level:

endpoint type DomainNounAndRDDRoleStereotype
exposes 
  operation verbFromDomainLanguage 
    expecting payload "DomainLevelTransferObject1" 
    delivering payload "DomainLevelTransferObject2"

Note that two similar refactorings were applied as well, Rename Endpoint and Rename Representation Element.

Example

In a publication management system, the remote service layer of a Web application might expose a Community API for Backend Integration, two foundational API patterns. The service might look as follows:

Service JabrefAPI {
    @PaperId add(@PublicationEntryDTO newEntry);

The notation in this example is CML, the tactic domain-driven design language supported by Context Mapper. Renaming the rather generic names yields this API design:

Service PublicationManagementFacade {
  // a state creation/state transition operation
  // (DTO = Data Transfer Object)
  @PaperId addPublicationToArchive(
    @PublicationEntryDTO publicationInformation);

Endpoint name, operation name, and parameter name are now free of technical jargon (except for the pattern names Facade and DTO, with the acronym being explained in the comment).

Hints and Pitfalls to Avoid

Consider consulting the following artifacts (before and after the refactoring):

  • Naming conventions on organization, unit, or project level. If you cannot locate such conventions, use this opportunity to establish them. Rename consistently and document the rationale for your naming decisions. For instance, such conventions might state that operation names start with verbs and followed by a noun from the domain vocabulary (see example above).
  • Glossaries and the Ubiquitous Language established by a domain model [Zimmermann and Stocker 2021]. Note that some community members advise that BankAccountAggregate is a bad choice of name while others recommend this domain-pattern pairing convention.
  • Coding guidelines, both general and language-specific.

Avoid special characters such as underscore _ in operation names because middleware and tools might not handle them correctly. The same holds for natural language-specific characters such as German “Umlaute”.2

Be careful with metaphors when naming things. Some might not be understood by parts of the target audience, others might cause unwanted reactions. Baseball fans, for example, know what a “curveball” and a “pitcher” are, but this sport is not as global as others. Apply the ones that you do choose consistently and do not mix them wildly.3 Ask yourself: Would the current name also work in another domain? In how many projects/APIs can this name be found?

Note that this refactoring is not straightforward to apply in HTTP resource APIs due to the REST principle “uniform interface”: One cannot rename the predefined HTTP PUT verb to something that has domain semantics. This constraint represents a deliberate design decision and is inherent to/in the REST style. It is one reason the Web works: it is not necessary to recompile the Web browser when there is a breaking change in the HTML layout of a website. URIs, however, can be changed; hence, the Rename Endpoint refactoring often is eligible.

This refactoring reverts itself. In code refactoring, there is Rename Method [Fowler 2018].

Move Operation is another operation-level refactoring.

The hints in “The Art of Readable Code” [Dustin Boswell 2011] also apply to API naming. Many programming language communities also have naming guidelines, such as the C++ Core Guidelines feature naming suggestions. A CppCon 2019 talk by Kate Gregory titled “Naming is Hard: Let’s Do Better” has good advice that applies when choosing API element names.

References

Dustin Boswell, Trevor Foucher. 2011. The Art of Readable Code. O’Reilly Media, Inc.

Fielding, Roy T., and Julian Reschke. 2014. “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content.” Request for Comments. RFC 7231; RFC Editor. https://doi.org/10.17487/RFC7231.

Fowler, Martin. 2018. Refactoring: Improving the Design of Existing Code. 2nd ed. Addison-Wesley Signature Series (Fowler). Boston, MA: Addison-Wesley.

Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. 1995. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.

Zimmermann, Olaf, and Mirko Stocker. 2021. Design Practice Reference - Guides and Templates to Craft Quality Software in Style. LeanPub. https://leanpub.com/dpr.

Zimmermann, Olaf, Mirko Stocker, and Stefan Kapferer. 2024. “Bringing Ethical Values into Agile Software Engineering.” In Smart Ethics in the Digital World: Proceedings of the ETHICOMP 2024. 21th International Conference on the Ethical and Social Impacts of ICT, 90–93. Universidad de La Rioja.

  1. The term “curse of knowledge” originates from technical writing. See, for instance, hint 5 in the blog post Technical Writing Tips and Tricks and a video lecture by Steven Pinker referenced in that post. 

  2. As a test, do ä, ö, ü render properly when you read this? 

  3. What happens if an elephant enters a room as a Visitor or crosses a Bridge? Should the Flyweight pattern be applied then? Or does it make sense to build a Factory in this case? What will Observers think about this Strategy? [Gamma et al. 1995