Top-level definitions

The sections below include the coding conventions with respect to top-level definitions.

General practices

  • Do not indent the top-level definitions.

    Do's

    Copy
    import ballerina/http;
    
    const MIN_AGE = 20;
    int repetitions = 0;
    
    service / on ep1 {
        ...
    }

    Don'ts

    Copy
    // This import is indented correctly.
    import ballerina/http; 
        
        const MIN_AGE = 20; // Not indented correctly.
        int repetitions = 0; // Not indented correctly.
            
    // Not indented correctly.
    service / on ep1 {
        ...
        }

Import declaration

  • Do not keep spaces between the organization name, divider /, and module name.

    Example:

    Copy
    import ballerina/http;
  • Imports should be sorted alphabetically, first by the organization name and then by the module name.

Constant declaration

  • Use SCREAMING_SNAKE_CASE for constant names.

    Example:

    Copy
    // don't
    const minAge = 20;
    const MinAge = 20;
    const min_age = 20;
    
    // do
    const MIN_AGE = 20;
  • The type descriptor can be omitted in a constant declaration unless the type descriptor is required to construct the value (e.g., provide defaults, provide expected types to determine the inherent type, etc.).

    Example:

    Copy
    // don't
    const int MIN_AGE = 20;
    const decimal TAX_RATE = 0.15;
    
    // do
    const MIN_AGE = 20;
    const TAX_RATE = 0.15d;
  • Explicitly defining the type descriptor can enhance readability, particularly when the constant is defined with a compound expression.

    Example:

    Copy
    // don't
    const COMPLEX_VALUE = (50 * 2 + 100) % 256;
    
    // do
    // The explicit `byte` type descriptor here improves readability. 
    // It ensures that `COMPLEX_VALUE` can be safely used wherever a `byte` is expected.
    const byte COMPLEX_VALUE = (50 * 2 + 100) % 256;

Function definition

  • Do not keep spaces between the function name and the open parentheses ( of the function signature.

    Example:

    Copy
    function func1() {
    }
  • If the function needs to be split into new lines due to it exceeding the max line length, you can break lines from the parameter list by moving only a parameter value to a new line and indenting it with four spaces from the starting position of the function.

    Example:

    Copy
    function getAddress(int value,
        string name) returns string? {
        ...
    }
    • You can break before the returns keyword and indent it with four spaces from the starting position of the function.

      Example:

      Copy
      function getAddress(int value, string name)
          returns string? {
          ...
      }
    • You can break after the returns keyword by moving the return value to a new line and indenting it with four spaces from the starting position of the function.

      Example:

      Copy
      function getAddress(int value, string name) returns
          string? {
          ...
      }

Service definition

  • Keep the listener inline with the service signature.

    Example:

    Copy
    service / on new http:Listener(9090) {
    ...
    }
  • When formatting service-level method definitions, block indent each element and follow the Function definition formatting guidelines.

    Example:

    Copy
    import ballerina/http;
    
    service / on new http:Listener(9090) {
    
        resource function get greeting() returns string {
            return "Hello, World!";
        }
        
    }
  • Block indent each method definition, and field definition inside a service definition.

Class definition

  • Block indent each field definition, method definition and type inclusion on their own line.

  • The init method should be placed before all the other methods.

  • For method definitions in the class definition, follow the Function definition formatting guidelines.

    Example:

    Copy
    class Person {
        public boolean isMarried = false;
        int age;
        string name;
    
        function init(string name, int age = 0) {
            self.age = age;
            self.name = name;
        }
    
        function getName() returns string {
            return self.name;
        }
    
        function setIsMarried(boolean isMarried) {
            self.isMarried = isMarried;
        }
    
        function getIsMarried() returns boolean {
            return self.isMarried;
        }
    }

Record definition

  • Block indent each of the field definitions (including the rest field) in their own line.

    Example:

    Copy
    type Person record {|
        string name;
        int...;
    |};
    
    // or
    
    type Person record {|
        int id;
        string name;
    |};

Reference record or object

  • Do not keep spaces between the * and the object name or the record name.

    Example:

    Copy
    *Person;
  • Also, block-indent.

    Example:

    Copy
    type UserId record {
        string id = "";
    };
    
    type User record {
        *UserId; // Reference to UserId record.
        string name = "john";
        int age = 20;
    };
    
    // or
    type Person object {
        string name;
    
        // Object function definitions.
        function getName() returns string;
    };
    
    class Employee {
        *Person; // Reference to Person object type.
    
        function init() {
            self.name = "John Doe";
        }
    
        function getName() returns string {
            return self.name;
        }
    }

"Star"

"Watch"