In this article, we will explore what a feature team is and how microservices can facilitate its work.
Before going into further detail about the topic, it is important to answer these questions: what is the problem we want to solve thanks to the organization in feature teams?
Have you ever found yourself in a situation where your team needs support from another team, and the contact person you need is very busy, has little time to spare, and puts you on hold?
In this type of situation, time-to-market automatically slows down and stress gets higher. Not only that, trying to go into production anyway can cause: low quality of the work, less tests, spaghetti code, unexpected events and bugs that typically occur at the least appropriate time.
This situation creates chaos and the system is out of control.
A practical example
Let's think about a Product Owner (henceforth PO) who manages an e-commerce and wants to send 3 features into production:
- Product Catalogue;
- Product Purchase;
- Product Review.
How does the PO manage them?
Typically, e-commerce activities have a mobile app, a website, and a set of back-end services that need to be developed.
Therefore, we will have two teams, one front-end, and one back-end, which will start working together on the first feature: the catalog.
At some point, a teammate of the front-end team needs support from the back-end team. The back-end team is available to help but needs time to better understand the request. The front-end team, while waiting for support, starts developing a new feature.
When the back-end team has understood the request and it is ready to meet and work on it, the front-end team is busy developing the new feature. So, it is a waste of time.
It is hard to align the agendas until, at last, there is time to meet to decide the next feature.
The work is handed from one team to another, and there is always a danger of delay.
How do we avoid this ping-pong?
Stop starting, start finishing: let’s stop starting new tasks until we have closed those in progress. It means that we need to close those tasks we spent time on but we have not put into production yet.
The code we write every day does not create value neither for the end-user nor for the business until it goes into production. So, why should we start new activities when those on which we have already spent time have not gone into production yet? Why don't we focus on closing those tasks first?
So, how should we proceed?
When two teams start working on a feature A, and there is a problem that forces a team to wait, the team that waits should not start developing a new feature but should use that time to work on what has been done.
For example, the team could improve code quality and test performances, conduct code reviews, and share knowledge. Therefore, the team could carry out activities that can be easily interrupted when the back-end team is ready to keep working on the problem that emerged.
In this way, it will be faster to close the first feature, move on to the next, speed up the time-to-market, and quickly bring what the customer demands into production.
This is a solution that works well when there is one problem at a time. Although, we know that problems can occur in the same phase, and we could risk spending more time fixing our code than developing.
In fact, this method applies well to certain systems. For example, ambulance corps and firefighters spend most of their time waiting in order to be ready to intervene, reducing the time of action when necessary.
However, in a work context where the goal is to reduce time-to-market at sustainable costs, this method may not always be the most effective.
How do we sync the two teams?
The appropriate process must be identified according to the business.
Let's go back to our PO, our back-end and front-end teams. But let’s turn the situation around:
The idea is to avoid having two teams working in parallel on back-end and front-end. The ultimate idea would be to have two teams working on single features vertically, combining back-end and front-end skills, and operating end-to-end throughout the life cycle of a feature.
What is a Feature Team?
It is a cross-functional team with UX/UI skills - implementation of graphic design - front-end and back-end development, API design and maintenance, knowledge of business logic, testing, deployment, and operations. In other words, it is a team that knows how to manage its features independently, as a small startup, with a view to what the end-customer wants and needs.
Having this kind of organization is not so easy. But it is a good way to have different teams that keep developing features following the stop-starting, start-finishing principle. In addition, if any difficulty emerges, the team has all the necessary skills to handle it independently.
Communication is easier. There is less stress. Quality and performance increase.
Know-how and skills: without them, the feature team struggles to collaborate
It is fundamental to know the business context and to have technical skills for a good team’s collaboration.
We know how difficult it is to be a real full-stack developer. What is important is that there is a specialization but with different skills that allow easily moving within a given situation. This is the T-shape model: verticalization on one competence but the ability to move horizontally on all the others.
If know-how and skills are missing, the team can’t be autonomous and ends up organizing itself into components rather than features. The organization in components is risky, because the components may not correctly fit together and lead to interdependencies which can generate the waiting lines we were talking about at the beginning.
The Conway’s Law
According to Conway's law, the corporate organization and how the areas communicate with each other are reflected in the company's IT system.
If a company is organized in silos, the organization will produce monolithic designs. IT will have monoliths. By defining how departments interact with each other, I will have IT systems that converse the same way.
So, let's try to build from scratch our IT system, first of all thinking about business aspects instead of architectural design.
Let's go back to our e-commerce with a series of features to implement: product availability, catalog, pricing, customers, logistics, reviews and customer care, communication engines, billing, etc.
If we take these features and divide them among our teams, each of them will have its own responsibility for the set of features.
So let's see how, starting from a business domain, we can build IT architectures that reflect the organization and, therefore, how the microservices architectural style can facilitate the work of feature teams.
It is important to refer to architectural style rather than design pattern when we talk about microservices because just as artistic styles are interpretable, the design used for microservices is also interpretable and must be contextualized as appropriate.
Nobody will tell how big a microservice should be, how granular, and how it should communicate. It always depends on the specific case.
Therefore, going back to our features, we can combine them into two microservices that will not be too granular.
These microservices won’t be too difficult to maintain and evolve. Monoliths are easier to create but they can’t evolve over time. If microservices are too granular, they will be hard to be orchestrated.
Once the division into two microservices has been made, it is necessary to consider the exposure on the Android and iOS apps and the web.
Back-end for front-end
The two feature teams that we have created and that respectively manage a microservice will surely have various intersections of skills and needs. These dependencies will lead to those waiting moments that we talked about earlier.
However, we can further reduce these moments by introducing the concept of the back-end for front-end. In a nutshell, as a mobile team that also works with responsibility on product services, we can decouple all back-end services with a front-end which also allows making a mock towards customer services. In the same way, the web team can decouple product services from customers’.
The back-end for front-end has the proximity logic that allows aggregating the data and exposing it in different ways. For example, tables can have different views on various devices.
However, teams evolve and microservices architectures are evolutionary too. For this reason, we might think about breaking the two previously created microservices and even build a microservice that manages all the logistics, which has grown over time with the business.
All services communicate with each other through an event broker and above it, we can put an API Gateway that decouples and makes this system a platform.
We are presenting evolutions that can take place over time. Teams start talking with each other thanks to the fact that everyone has a clear business vision and can share information and data.
At this point, it becomes important to understand how to deliver the system and how to contribute to these services without creating the expectations and queues at the origin of our consideration.
Let's assume we have one sprint lasting one week and, for each sprint, we release something in production.
In the first week, our three working teams develop features, without finishing them all for the end of the sprint.
What do we do? Do we release all the features, even if they are not 100% completed? Doing that could create little system reliability and have negative repercussions on our work.
Then, we introduce the concept of feature toggles: we release our features disconnected, so we can test them, even with A / B testing, or leave them totally off. In the meantime, the team keeps working and turns on the toggles when it is time to release.
In this way, with a sustainable and recurring rhythm, it is released into production without the teams having to be hyper-synchronized for the release of the features.
In fact, we must remember that the features are not user stories but aggregates of stories; therefore, if within a sprint we complete user stories that do not create value for the end-user, we normally do not release them. We only release what are tangible features.
The concept of contribution
It may happen that we have a problem with a component, for example a single sign-on (SSO) page made on the web and that needs to be integrated on mobile. How can we avoid bottlenecks?
We ask for help and introduce the concept of contribution, which comes directly from the open-source world.
The idea is to create an ecosystem within which the code belongs to everyone.
Collective code ownership is one of the extreme programming practices and in open-source it has been declined by creating teams that are maintainers and teams that are contributors.
If we manage to bring this concept of maintainer and contributor within the company, we can effectively evolve the conversation among teams and avoid many bottlenecks.
Obviously, the contributor team will be slower than the maintainer team, but it acquires know-how over time and allows to reduce many future slowdowns.
Of course, it's not simple.
How do we make people work together and become experts on something they didn't know the day before?
We need to keep these 4 points in mind:
- A product, a product owner, a product backlog, a feature team. With single central coordination and with a focus of all teams on the business value generated for the user, each line of code creates value for the end-user. Nothing is done beyond what can generate greater value for the end-user. What belongs to the back-end too.
- Standards and processes emerge from people's work. Start doing regular mob programming, code writing of all the teams together, even 8 people at a time, where we can talk about why code is written in that way, what problem it solves, etc. Do regular code reviews to define code writing standards.
- Don't fall in love with technology: use unconferences to give everyone the opportunity to present ideas, exchange ideas, and also experiment with new languages.
- Always practice: as at school we used to practice expressions, writing code is also a profession that requires a lot of exercises. Kata is an activity that helps we improve through the performance of simple exercises, but always at the maximum of our potential and development skills.
- Feature teams are not only an opportunity from a technical point of view but also from a business point of view because they reduce time-to-market;
- Microservices are architectural styles, not architectures. If aligned with the business, they help teams communicate;
- The code belongs to everyone and everyone has the right to work on it and the duty to keep it clean and performing. The open-source context favors this aspect;
- Organization and architecture emerge and evolve from a good conversation among people. We do not copy and paste other people's models but we make ours emerge.
This article traces the talk by Giulio Roggero, CTO of Mia-Platform, presented on the occasion of the events: GDG Dev Party 2020, FEVR Verona 2020, CloudCOn on Air 2020.
You can review Giulio Roggero's talk on GDG Dev Party 2020 at this link.
© MIA s.r.l. All rights reserved