Code reviews are a crucial part of the software development process, helping to maintain code quality, share knowledge among team members, and improve the overall health of the codebase. Here is a detailed guide for performing code reviews in GoLang.
The primary purpose of code review is to ensure that the overall health of the company’s codebase improves over time. To achieve this, a series of trade-offs must be balanced.
First, developers need to make progress on their tasks. If improvements are never submitted to the codebase, then it cannot improve. Additionally, if a reviewer makes it overly difficult for changes to be approved, developers may become discouraged from making future improvements.
On the other hand, it is the reviewer’s responsibility to ensure that each change list is of a quality that maintains or enhances the overall health of the codebase over time.
A key point to remember is that “perfect” code does not exist—only better code. A change list that, overall, improves the maintainability, readability, and understandability of the system should not be delayed for extended periods simply because it is not “perfect”.
- Reviewers must understand the context and goal of the change.
- The code review must start from the perspective of accepting the code, rather than looking for reasons to reject it.
- Reviewers must provide constructive feedback and be respectful of the author's work.
- Authors should include enough information in the PR description to make the reviewer's job easier.
- It’s recommended to split technical tasks, product tasks, and refactoring into separate tasks and PRs to simplify the process.
- It’s recommended to split large PRs into smaller ones (PR limit is 400 lines) for better comprehension. Note: code-generated files are not included in this limit.
- Recommended to request changes only for critical issues, such as:
- violations of the service's overall architecture or established approaches for solving similar issues;
- evident and significant performance issues;
- logic errors.
- The code must adhere to the established GoLang style guide and project-specific conventions.
- The code should be clear and easy to understand, avoiding clever tricks and complex structures.
- The code should be DRY (Don't Repeat Yourself); code duplication should be avoided.
- The code should follow Clean Architecture principles.
- The code should follow the YAGNI (You Aren't Gonna Need It) and KISS (Keep It Simple, Stupid) principles.
- The code should not contain any debugging or logging statements left over from development.
- All errors must be properly handled. Ignoring returned errors without explanation should be avoided.
- Use of
panic
should be justified, as Go favors explicit error handling.
- The code must include unit tests that cover both positive and negative cases.
- Tests must pass before the code can be merged.
- Mocks should be used for testing functions that depend on external services.
- Bug fixes should be covered with tests.
- Unnecessary allocations and computations should be avoided.
- During the review process, if the code performs concurrent operations, reviewers should pay particular attention to these, verifying correct handling of synchronization, data races, and deadlocks.
- The code must not contain any potential security issues, such as hardcoded credentials, sensitive data in logs, or risks of SQL injection.
- Input validation and error messages must be implemented correctly to prevent exposure of internal implementation details.
- All input must be validated.
- Publicly exposed APIs, functions, methods, and types should have GoDoc comments that explain their purpose and usage.
- Complex parts of the code should include comments explaining their functionality.
Providing feedback in a code review is a skill that develops with practice. Your comments should be helpful, clear, and respectful. Here’s a guide on how to leave constructive code review comments.
Rather than simply stating that something is wrong, try asking a question. This approach encourages the author to think about their code from a different perspective and can often lead to a better solution.
- Could this function be refactored to avoid repeating this code block?
- I'm not sure, I understand the logic here. Could you explain why you chose this approach?
Vague feedback can be challenging to act upon. Be specific about what you’re referring to, and, if possible, provide examples or suggestions for how the code could be improved.
* this function is doing too much and might be a good candidate for refactoring. Perhaps we could extract this logic into a separate function?
* I see we're duplicating this logic in several places. Could we create a utility function to handle this?
If you’d like to suggest an improvement on a style point not covered in the style guide, prefix your comment with “Nit:” to indicate that it’s a minor suggestion. This lets the developer know it’s a nitpick you think would enhance the code but isn’t mandatory.
It's important to remember that you're reviewing the code, not the author. Avoid using personal pronouns like "you" and "your". Instead, refer to the code itself.
* this function could benefit from additional comments.
* this code block seems to handle several different concerns. Could we split it into separate functions for clarity?
Finally, remember that the goal of a code review is to improve the code, not to criticize the author. Be respectful and always provide feedback in a constructive manner.
* I think there might be a more efficient way to handle this. Have you considered using a map instead of a slice?
* this function is a bit long and complex. It could be simplified and made easier to read by splitting it into smaller functions.
Code reviews are a learning experience for everyone involved. Approach them with an open mind, a positive attitude, and a willingness to learn while helping others learn as well.