DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Popular
  3. Open Source
  4. Backward compatibility, even inside a single project

Backward compatibility, even inside a single project

Giorgio Sironi user avatar by
Giorgio Sironi
·
Jul. 08, 13 · Interview
Like (0)
Save
Tweet
Share
4.67K Views

Join the DZone community and get the full member experience.

Join For Free

Today we're talking about backwards compatibility, in the context of the applications you developed during your daily work.

To avoid growing to an unmanageable size, applications usually gain dependencies oriented towards:

  • internal libraries or frameworks of your company.
  • published open source (or closed source) software.

In any case, the application needs code that lives in a different version control repository.

Backwards compatibility needs to be taken into account whenever you're not acting on the leaf of the dependency graph but on all the other intermediate nodes. I'm both an open source developer as a proprietary one, so I have some tips that can be applied to both internal libraries and open source one.

Adding functionality

Adding stuff without impacting compatibility is usually easy, with a potential issues for the internal consistency of the code. However, since the new API methods were not in place before, you have much freedom to add them as long as you do not clash with the existing ones. Just adding functions, methods, or URL is one of the safest strategies.

Even discounting the cost of maintaining all the old and new public facets, there are a few concerns however:

  • good names: if they are in use, they cannot be recycled for the newer and better version of methods. Most programming languages mitigate this via method overloading or dynamic checks on the type of input parameters.
  • consistency: if old methods all have that get*() prefix and you want to add a new one, you're compelled to name it getSomething() instead of something() or exportSomething(receiver), examples of other styles and structure.

Deleting functionality

The lifecycle of methods and functions is longer when exported publicly, since other projects cannot atomically switch to new names or versions but need an interim period in which they can use both.

Furthermore, if you're working with Feature Branching or Pull Requests, this applies even inside a single project (albeit with fortunately shorter cycle periods). If you remove methods from a master branch along with all references, you're still missing branches that were started from master before the removal, and that upon merge may break totally for the missing functionality they were relying on.

So I produced a little checklist to remove public methods and URLs that takes little effort but several days of elapsed time while you wait between steps.

1. Deprecate the functionality.

Mark the method with a @deprecate. If your language does not support the annotation, write an error_log('deprecated feature X') as the first line of the method implementation. I'm also considering an X-Deprecated HTTP header to signal an API that has started the removal process.

2. Wait for all branches to reenter in master via merging.

The waiting period for this should be reasonable, and it benefits from keeping user stories small and branches short-lived.

While you wait, new branches depart from the current master without the feature, and as such can be ignored in the waiting list above.

3. Actually remove the feature.

This process can take a lot, even several weeks. However, the time you actually spend is not much; you just need to wait and to remember to take the next steps a week from now.

Modifying functionality

Modifying the behavior of methods can often be done with compatibility, and this is part of good factoring: isolate a change inside an implementation while the rest of the world continue to send the same events to it. REST in its Hypermedia API One True incarnation tries do do this by hiding all URLs except the starting one.

However, when the contract between the client and the server breaks, it's much easier to avoid modifying the functionality and to remove it and add it with a different name by following the methods described above.

Usually you can also find more descriptive and fitting names for the new entities to add, since a lot of background processes in your designer's head have come to conclusion during the time you contemplate the original functionality.

The exception, of course, is the possibility of distinguishing between old and new clients by a version field. This however enlarges the surface area of the APIs, since the version must be passed in with other inputs (or it must be deduced from the current inputs with heuristics.)

Compatibility (chemical) Open source

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Application Architecture Design Principles
  • Multi-Cloud Integration
  • Microservices 101: Transactional Outbox and Inbox
  • How To Build a Spring Boot GraalVM Image

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: