DZone
Web Dev Zone
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
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Web Dev Zone > Backward compatibility, even inside a single project

Backward compatibility, even inside a single project

Giorgio Sironi user avatar by
Giorgio Sironi
·
Jul. 08, 13 · Web Dev Zone · Interview
Like (0)
Save
Tweet
4.51K 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

  • Purpose-Driven Microservice Design
  • Top 7 Features in Jakarta EE 10 Release
  • 7 Ways to Capture Java Heap Dumps
  • Top 10 Automated Software Testing Tools

Comments

Web Dev Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • 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:

DZone.com is powered by 

AnswerHub logo