Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Best practices for business versioning within Web APIs

+2
−0

Context

Our team is developing a solution mainly composed of several microservices relying on ASP.NET Core.

We have decided that the simplest and most cost-effective solution would be for services to support multiple versions at the same time at pod level (the same application might expose multiple versions at the same time as opposed to running different pods for different versions).

We have also decided to avoid function-level versioning logic (i.e. if statements checking for something related to a specific version), so that it is easy to phase out an older version once no client uses it.

We expect a maximum of three versions at the same time.

While controller-level versioning (API versioning) is covered in numerous articles, I cannot find many details about how to version the underlying services.

Let's consider a simple example:

  • POST /v1/messages calls MessageService which in turn relies on a validator (MessageApiModelValidator) to validate the input
  • a MessageMapper translates the MessageApiModel to Message (the EF model)
  • a repository (MessageRepository) is called to persist the message

Let's consider a breaking change at the MessageApiModel level (e.g. a new mandatory property is added). This means that MessageApiModel, MessageMapper and possibly MessageService will be versioned.

Option 1 - keep the class names

We have also aligned to keep the older versions in special folders. The structure would look like this:

Messages 
│
├── _versions
├──── v1
├────── Mappers
├──────── MessageMapper.cs
├────── Models
├──────── MessageApiModel.cs
├────── Services
├──────── MessageService.cs
├────── Validators
├──────── MessageApiModelValidator.cs
├── Mappers
├──── MessageMapper.cs
├── Models
├──── MessageApiModel.cs
├── Services
├──── MessageService.cs
├── Validators
├──── MessageApiModelValidator.cs

The breaking changes are implemented directly in the "normal" folder structure (outside of the _versions folder) and the older versions include a clone of the existing affected files (only the changes files are cloned).

  • the main pro I see is that we keep the class names clean.
  • the main con I see is that by having the same class name, one needs to be very careful to reference the correct class. This is especially important due to the auto-import feature of Visual Studio (might pick the wrong version and not realize it).

Option 2 - apply explicit versioning on class names

In this case the folder structure is almost identical, but all affected class names get the version as a suffix:

Messages 
│
├── _versions
├──── v1
├────── Mappers
├──────── MessageMapperV1.cs
├────── Models
├──────── MessageApiModelV1.cs
├────── Services
├──────── MessageServiceV1.cs
├────── Validators
├──────── MessageApiModelValidatorV1.cs
├── Mappers
├──── MessageMapper.cs
├── Models
├──── MessageApiModel.cs
├── Services
├──── MessageService.cs
├── Validators
├──── MessageApiModelValidator.cs

The main pro I see is that when working with an instance it is very clear which version is used. Also, there is no need for namespace disambiguation (namespace alias).

The main con I see is that the class names look strange and somewhat redundant (the namespace already includes the version).

Regardless of the option, phasing out a version means removing the folder(s) for that version and fixing a few compilation errors (e.g. service registration).

What are the best practices surrounding business class versioning for breaking changes that affect multiple classes?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

0 answers

Sign up to answer this question »