When To Write Comments In Your Code

…and when you probably don't need to bother

When To Write Comments In Your Code

Many programmers have a love/hate relationship with comments. This usually means they love reading them but hate writing them 🤣

So what is your view on comments? Are you in the camp that all software should be fully documented as if it shipped with the framework itself? Or do you believe in the fabled "self-documenting code"?

Well I put it to you that both of these extremes are wrong. It is true that nice clean code can be largely self documenting, it is also true that having detailed comments on every public class, function and property can greatly speed up development speed of the one using it - despite the time cost of writing the comments.

The correct amount of commenting is probably somewhere in the middle, but how do you know where to draw the line? Well over the years I've come to realise that comments should be enforced over what I call knowledge boundaries. A knowledge boundary is somewhere that two people's expertise crosses over and they need to communicate in the same language.

Venn Diagram

A classic example of this is front-end and back-end developers. A back end developer builds an API and a front end developer builds a web app that consumes the API. You don't need to document or comment the code inside the API, you don't need to document the code inside the web app, but you do need to document the API endpoints, the "service contract" if you like. And document the hell out of them! I'll give you an example...

Back End Code (unhelpful comments)

public class UsersController : Controller
{
    [HttpPost]
    public IActionResult InsertUser(NewUserRequest user) 
    {
        // Add the user to the database.
        _userRepository.Add(user);

        // This returns a 201 Created status code.
        return Created();
    }
}

class User 
{
    public string Email { get; }

    public string[] Roles { get; }
}

Front End Code (unhelpful comments)

class UsersApi {
    
    insertUser(user) {
        // Use axios to POST the user to the api
        axios.post('/users', user);
    }
}

Why are these comments unhelpful? Well think about who will read them. Comments like these are often written with the justification that a new developer may come along and wants to understand the code.

Well I would argue that in the real world neither of these is an issue. The back end code above is written in C# and I think it's safe to assume that any competent C# developer will be familiar enough to understand what _userRepository.Add(user) does. Equally you'd hope they were familiar enough with ASP.NET Core to know that return Created(); will return an ActionResult object that sets the status code to 201. If they don't know these basic things then you have bigger issues, but think it's fair to assume they will know. What your average C# backend developer may not be aware of, however, is how to use axios in the front end example. Or how the front end code is even architected. Equally, for your front end JS developers they will know what the API does but they can't be expected to know which properties exist on the User object, which HTTP status codes they might expect to get from this endpoint, etc.

Here is a much better way of commenting the code...

Back End Code (helpful comments)

public class UsersController : Controller
{
    /// <summary>Creates a new user</summary>
    /// <param name="user">The user details of the new user</param>
    /// <response code="201">The user was created</response>
    [HttpPost]
    public IActionResult InsertUser(NewUserRequest user) 
    {
        _userRepository.Add(user);
        return Created();
    }
}

/// <summary>User details of a new user</summary>
public class NewUserRequest
{
    /// <summary>The user's email address</summary>
    public string Email { get; }

    /// <summary>Array of role names for the new user</summary>
    public string[] Roles { get; }
}

Front End Code (helpful comments)

class UsersApi {
    
    /**
     * Inserts a new user by POSTing to the /users endpoint of the api
     ** /
    insertUser(user) {
        axios.post('/users', user);
    }
}

Sure - those comments are a lot more verbose because they use C#'s XML comments and JDoc comments respectively, but they add so much more useful information. The back end comments can easily be turned into a Swagger spec, the front end comments can be used by IDEs such as VSCode. The NewUserRequest model can even be turned into a Typescript model using a package like Typewriter, including comments. By commenting like this the front and back-end devs have made each other's life so much easier!

    James Charlesworth

    Hi, I'm James

    I've worked in software development for nearly 20 years, from junior engineer to Director of Engineering. I'm here to help you get your foot on the next rung of your career ladder. I post weekly videos on YouTube and publish guides, articles, and guided project tutorials on this site. Sign up to my newsletter too for monthly career tips and insights in the world of software development.

    Related Project Tutorials

    Read Next...