Software development has evolved and over the years we’ve learned that software cannot be built in a silo. At TribalScale, we work closely with clients, demoing weekly releases and re-prioritizing, or even rewriting requirements to make sure we deliver the best product. This can be challenging and requires a lot of coordination between all team members. In an Agile environment, backend projects have an added level of complexity. For one, requirements change quickly and you don’t have the benefit of knowing all requirements before starting the project. Two, stakeholders don’t always have the technical knowledge needed to understand the scope of the project, especially because there are few tangible or visual components.
At TribalScale, I usually help with projects centered on backend needs. Over the years, I’ve faced many challenges and have learned many helpful lessons along the way. Below are some tips that will help with backend development and running a backend team.
Note: While this is written from a consulting perspective the same approach can be applied to a product-based company. After all, at TribalScale, the client is treated as an extension of our team.
1. Clarify Requirements
Backend requirements tend to be technical and dense. Both the client and the Product Manager (PM) may not fully understand the pieces that need to be completed to finish a larger piece of functionality. This means that a PM needs to rely more heavily on their Engineer to break a feature down. A PM can first gather high level requirements from the client, and then take the time to break it into digestible stories with the Engineer.
Story writing can be broken down into 3 steps:
2. Decide on Owners (or who accepts stories)
Once a feature is broken down, stories might become too technical for the client to understand. It is important to determine which stakeholder can accept these stories. If you are working with a full-stack team it might make sense to have the frontend team accept the backend stories. The frontend team may be from the client or from your own team. It might also make sense to bring in a technical person from the client’s team to accept or validate the stories.
3. Endpoint Expectations
If the client company is technical, they should have API endpoints defined and documented. However, the most disastrous backend projects tend to be those without a clear definition, or at least a vision for API endpoints. Endpoints tend to be defined ad hoc and result in a haphazard, Frankenstein-like structure.
If your team is only creating the backend, the API should be defined (endpoints, parameters, etc.) by the client, with guidance from your team. If your team is engaged to create a full stack project, the backend should be collaboratively defined by the frontend and backend teams. It is important to define these endpoints early on, so that there aren’t any surprises for either team.
4. Following Standards
It is very important to have an agreed upon structure for an API endpoint. An ever-changing API is the stuff of nightmares for a frontend team. It is also important to make sure that the API is relatively flat. The deeper a frontend team needs to traverse through an API, the more likely are mistakes and bugs.
Hopefully the client already has standards defined for their endpoints. Just like code, it’s important that endpoints can be easily transferred to the client. This means that they should look and function like the client’s other endpoints. If the client does not follow a standard, it can be helpful to follow a predefined standard like: JSON API, or JSend.
This also means that it’s important that errors on the backend are handled consistently. To give the frontend an idea of what’s going wrong, a specific status code like 400, 404, etc., should be generated when possible. If there is a general error detected, a 500 error should be returned.
It is okay if your endpoint needs to change from time-to-time, but be sure to version them. Do this by including a version number in your endpoint path. This will allow you to update your endpoints with new versions, without breaking legacy applications that are dependant on them.
5. Need for Tests
Backend code lends itself well to tests. There is no visual component, so tests can solely focus on functionality. The tests should serve as a health check on the project, and as living documentation for its functionality. Other developers should be able to quickly navigate through tests and understand the purpose of a given function.
6. Test Coverage
There are many test coverage tools out there. Make sure to use one that gives visibility on the number of tests being created, this gives the client an understanding of what is being created, and makes sure the Engineers keep up to date with tests.
Note: It’s important to be aware that code coverage can only really help show what is not covered by the code, it will not tell you if the code is well tested or clearly tested.
7. Time for Optimization
Depending on client requirements, there might be a need for time to optimize the solution. Trying to optimize while creating functionality is very difficult, and can lead to very messy and coupled code. Furthermore, in an Agile environment, requirements may not be concrete. It is important to first focus on functionality and then revisit the code for refactoring and optimization. Time should be allocated to focus on optimization in the release cycle.
8. Managing Client Expectations
Depending on the clients background, they may or may not put an importance on backend work. Just like with any other project, it is important to give a client as much visibility as possible as to what is currently being worked on. This helps keep the client up to date with a project’s timeline, even if they are not technical.
9. Portability and Dependencies
Backend work tends to have a lot of dependencies. This is even more true in a microservice environment. It can sometimes be difficult to mimic the environment that the backend will eventually be deployed to. During project inception it should be determined how the backend team’s environment will be set up. Likely, the client will already have a solution for their own developers, it is important that due diligence is done to make sure this setup will work for your team.
For portability, a docker solution can help make setup time shorter in the future. This will also allow for continuous integration (CI) and continuous deployment (CD) setup through concourse.
I hope some of my learnings and tips help you with your own project. Just like everything Agile, this is a learning process and not everything works for everyone. Are there methods that you use that weren’t mentioned? Is there something here that you disagree with? Let me know in the comments below.
One of TribalScale’s first employees, Lawton is an Agile Software Engineer and Engineering Manager. He has years of experiencing developing and leading teams for some of the biggest brands. A love of all things nerdy has led him down the dark path to programming. An oddball at heart, his interests also include hiking, travelling, musicals, board games, and what he calls ‘dancing.’