Coding Standards for Backend Code Development
In backend development, adhering to coding standards is imperative to ensure consistency, maintainability, and reliability in software systems. They collectively form the foundation for robust and efficient backend development. By following these standards, development teams can streamline collaboration, enhance code quality, and strengthen code security.
General Guidelines
We adhere to these general guidelines to ensure consistent, maintainable, and reliable backend code development. Follow these guidelines as you build technology adapters to integrate technologies that are not available out of the box in the Calibo Accelerate platform.
-
Unit Testing
Incorporate comprehensive unit test cases for any new features.
-
Test Refinement
Address and rectify any issues in existing unit test cases when making new changes.
-
Code Style Consistency
Implement a consistent code style, such as Checkstyle, to ensure uniform code formatting.
-
Static Code Analysis
Enhance our static code analysis by intensifying the addition of unit test cases and adopting tools for tracking and enforcing quality.
-
Automated Merging
Enforce gated and automatic merging of feature branches through Pull Requests, coupled with quality gates.
-
Integration Testing
Introduce integration testing to validate code before promotion to higher environments.
-
Performance Testing
Develop performance tests for both existing and new APIs as part of our performance test suite.
-
Distributed Tracing
Enable distributed tracing mechanisms to pinpoint performance bottlenecks effectively.
-
Health Check Endpoints
Ensure that every service incorporates health check endpoints.
-
Circuit Breaker Fallbacks
Implement a circuit breaker fallback mechanism in every service to gracefully handle failures when making direct calls to other services.
-
Service Discovery
Mandate the use of service discovery mechanisms for REST calls, avoiding direct communication with bare URLs.
-
SonarQube Integration
Integrate SonarQube and maintain uniform Checkstyle compliance across all services, with automatic publication on every build.
REST API Review Guidelines
Calibo follows the microservices architectural paradigm, which has led to the creation of numerous APIs within our ecosystem. To ensure the highest level of consistency and compatibility, we meticulously adhere to industry-established standards for our REST endpoints. Our commitment to quality includes regular code scanning to validate compliance with these standards.
-
Resource Naming as Nouns
- URIs should represent resources using nouns.
-
Avoid indicating CRUD (Create, Read, Update, Delete) operations in URIs.
Example: Use /users/{id} instead of /getUser.
-
Pluralized Resource Names
-
Typically, resource names should be pluralized for collections.
-
Example: Use /users for a collection and /users/{id}/address for a singleton resource.
-
-
Hierarchy with Forward Slashes
-
Use forward slashes to depict hierarchy between individual resources and collections.
Example: /users/{id}/address is under /users/{id, which is under /users.
-
-
Punctuation for Lists
-
For non-hierarchical relationships like lists, use punctuation marks like semicolons or commas.
Example: /users/{id1},{id2} to access multiple user resources.
-
-
Query Parameters When Necessary
-
Allow query parameters in the URI for filtering and querying.
Example: /users?location=USA to find users living in the United States.
-
-
Lowercase Letters and Dashes
-
Use lowercase letters for resource names.
-
Replace underscores with dashes.
Example: /users/{id}/pending-orders instead of /users/{id}/Pending_Orders.
-
-
Intuitive Naming (No Jargon)
-
Opt for intuitive and commonly used words.
-
Avoid jargon or complex terms.
Example: /users/{id}/card-number instead of /users/{id}/pan.
-
No Abridging:
-
Avoid abbreviating endpoint or resource names.
-
Clarity is more important than brevity.
Example: /users/{id}/phone-number instead of /users/{id}/tel-no.
-
-
No File Extensions:
-
Omit file extensions (for example, .xml) from URIs.
-
Use Content-Type header to specify the format.
Example: /users/{id}/pending-orders instead of /users/{id}/pending-orders.xml.
-
-
No Trailing Forward Slash
-
Avoid adding a trailing forward slash to URIs.
-
Keep URIs clean and concise.
Example: /users/{id}/pending-orders instead of /users/{id}/pending-orders/.
-
Code Review and Scanning Process
Code review and scanning stand as the cornerstone of our commitment to delivering high-quality software. Our code review and scanning process is based on the industry best practices which helps us ensure that the Calibo Accelerate platform:
-
Adheres to the highest standards of quality and security, safeguarding against potential threats.
-
Remains flexible and extensible, readily adapting to evolving business needs with minimal changes.
-
Reduces rework by detecting and addressing issues swiftly.
-
Demonstrates robustness, guaranteeing long-term stability.
-
Accelerates delivery, aligning technology with business requirements..
To achieve these standards, we employ a stringent code review and scanning process, combining the automated and manual techniques which include:
Automated Code Scanning
-
By using robust tools, we automatically scan code during various stages, including commits, merges, and beyond.
-
Our integrated IDEs detect and flag issues, vulnerabilities, and compliance deviations early in the development cycle.
-
We scan Docker images, Helm charts, third-party libraries, and automation scripts, such as Terraform configurations, among others.
Manual Review
-
Our senior technical experts conduct manual code reviews at multiple stages, such as development, pull requests, and bug fixes.
-
These reviews encompass critical factors like reusability, abstraction, performance, adherence to business requirements, and input/output verification.
Code Security Review
Our rigorous security review scrutinizes code for vulnerabilities, including injections (for example, SQL, script, header), potential confidential data leaks, insecure secrets handling, token and certificate validation, API key management, and endpoint security. We use Synk for security scanning purposes.
Patterns Review
We have refined a set of high-standard coding patterns, to enhance reusability, flexibility, and ease of integration.
These proven patterns include
-
Adapter patterns
-
Repository patterns
-
Orchestrator patterns
-
Message handling patterns
-
Threading patterns
-
Design patterns (creation, structural, and behavioral).
Generic Review Guidelines
Follow these guidelines to maintain high quality standards in your backend code development.
-
Proper REST URL Naming
Verify that REST URLs follow naming conventions. See REST API Review Guidelines.
-
Usage of Constants for Free Strings
Replace free strings with constants for improved maintainability.
-
Optimized Query for Native Queries
Ensure optimized query usage, especially with native queries.
-
Proper Error Message Handling
Validate error message handling, including proper error reporting. The message implementation should adhere to the error handling framework of the platform.
-
Error Messages in Config Store
Store error messages in a centralized configuration store.
-
Add New APIs to Config Store
Whenever a new API is consumed, add its configuration to the store.
-
Configurability
Try to make properties configurable whenever possible.
-
Version Control for Breakable Changes
Increment the version for breakable changes like contract modifications.
-
Add New Features Behind Feature Flag Capability
Any new feature should be behind the feature flag framework of the platform.
-
No Commented Code
Remove commented-out code.
-
Avoid API Calls in Loops
Ensure no API calls or methods calling APIs within loops.
-
Threading for Cases
Any logic that demands long running loops can be redesigned properly to consume threading framework of the platform.
-
Descriptive Variable Names
Use meaningful and understandable variable names.
-
CamelCasing in Variable Name
Start variables with a lowercase letter and then capitalize the first letter of every subsequent word.
-
Reference Parameters
Avoid using reference parameters and use value parameters as much as possible.
-
Proper Code Formatting
Enforce consistent code formatting throughout the code base.
-
No Stale or Dead Code
Remove stale or dead code that serves no purpose.
-
Avoid Long Methods
Break down lengthy methods into smaller, more manageable ones. Each method should not be more than 20 lines at most.
-
Proper Class and Interface Names
Start class and interface names with an uppercase letter and then capitalize the first letter of every subsequent word.
-
Modular Programming
Classes should be modularized as per functionality and should be reusable.
-
Open for Extension and Closed for Modification
Classes implemented should always be extensible but modifications to the same class for new functionality should be avoided.
-
Single Responsibility Principle
Every class and interface should have a single responsibility which further helps in maintaining the code. So that it changes only when it is required to change and not for all cases.
-
Interface Segregation Principle
Interfaces should be very specific to the requirement. Multiple interfaces are good but overloading the same interface with unwanted methods is not allowed.
-
Avoid Long Classes
Classes should not be more than 200 lines of code which will impact readability.
-
No Circular Dependency
Eliminate circular dependencies between modules or components.
-
Null Checks and Handling
Implement proper null checks and error handling for null values.
-
Utilize StringUtils and CollectionUtils
Use utility classes like StringUtils and CollectionUtils for emptiness checks.
-
Exception Handling with ExceptionUtils
Utilize ExceptionUtils for printing stack traces.
-
Static Utility Methods
Create utility classes with only static methods that are stateless.
-
Non-static Methods in Components
Use components for non-static methods that may have state.
-
No Unused Variables
Remove unused variables from the code.
-
Log Sensitive Info with Masking:
Use debug logs for sensitive information, ensuring data masking where needed.
-
Info Logs for Other Information
Utilize info logs for non-sensitive informational messages.
-
Avoid Multiple Loops
Minimize the use of multiple nested loops, consider using ExecutorService for optimization.
-
Resource Management
Ensure resources are properly closed to prevent memory leaks.
-
Transactional Methods
Use transactions appropriately for methods that require them.
-
Asynchronous Calls
Employ proper asynchronous call patterns when needed.
-
Try Block with Resources
Use try-with-resources for managing external connections.
-
Script Management
Scripts should not be present in lower or upper environments.
-
Local Validation for Scripts
Validate scripts locally for Flyway validations before check-in.
-
Documentation
Documentation is mandatory to be added on methods and classes. Code style checker tool gives warning if documentation is not added properly.
-
Copyright Statement
Adding a copyright statement to all new files is mandatory.
-
Avoid Too Many Arguments
At the most four to five arguments should be used in a method. If more are required, create a bean out of arguments.
-
Config File Formats
Config files are yaml-based, so put proper indentations and cross check locally for any error.
-
Error Messages and Error Codes
Put error codes as per standard defined in the configuration file under the mentioned section of the configuration.
Pull Request Reviews
Calibo recommends two rounds of code review:
Peer Review:
-
Team Collaboration
Collaborate with team members for peer reviews.
-
Feedback Focus
Gather feedback on the following:
-
Reusability: Assess the code's potential for reuse in other contexts.
-
Impact on Other Use-Cases: Evaluate how the changes affect existing use-cases.
-
Test Scenarios: Ensure comprehensive test scenarios are considered.
-
Architecture Review:
-
Engage Architect Team
Involve the architecture team in the review process.
-
Security Assessment
Assess the code for security considerations.
-
Performance Evaluation
Review the code with a focus on performance.
-
Scalability Analysis
Evaluate code for scalability concerns.
-
Usability Check
Verify usability aspects of the code.
Testing Requirements
Our testing guidelines help you establish standard quality assurance practices. They are designed to facilitate comprehensive testing and validation of your adapter, ensuring it aligns with our commitment to deliver superior functionality and an exceptional user experience.
-
Local Testing
Perform local testing with the set of development ecosystem prepared for the use case development.
-
Integration Testing
After the local testing is completed with all use cases, the developed piece can be promoted to integration environment for testing with other modules.
-
Collaborative Testing
Promote collaboration between DEV and QA teams to create comprehensive test cases.
-
Requirement Coverage
Ensure that test cases cover all specified requirements.
Members from development and QA teams must work together to have test cases ready to check where all the requirements are fulfilled.
Performance, Scalability, and Reliability (PSR) Requirements
The following PSR requirements serve as our blueprint to help you build high-performing, and dependable technology adapters.
-
Performance Optimization:
Prioritize performance considerations in every use-case development.
-
Data Efficiency:
Ensure minimal data retrieval for UI requirements, fetching only necessary data.
-
Response Time Target:
Strive to maintain response times under 2 seconds for every call in the Calibo Accelerate platform.
-
Concurrent User Execution
The functionality should be able to execute with a minimum load of 200 concurrent users with the mentioned response time without any failures.
-
Minimum Throughput
A minimum throughput of 1000 should be achieved for 200 concurrent users.
-
Maximum CPU Utilization
Under any circumstances, the CPU utilization of any service should not breach the 80% mark of available resources.
-
Maximum Memory Utilization
Under all conditions, the memory utilization should always be within 75% mark and available heap memory within 50% mark.
-
Graceful Degradation
In case of failure, the code piece should be able to degrade with proper notification.
-
Self-Recovery Mechanism
Under stress and failure scenario, the code should be able to recover to original state with proper circuit breaking logic.
-
High Availability
The services should be highly available under all circumstances.
-
Fault Tolerance
The logic should be able to handle minor failures and should not propagate errors leading to service unavailability.
In summary, these coding guidelines for backend development help you create efficient technology adapters for integrating with the Calibo Accelerate platform. By following these best practices, you can build code which is maintainable aligning with industry standards and optimized for performance.
What's next? Review Process |