Demonstrate example code in production

When implementing a new class, test, table or API end point, it is useful to have examples that demonstrate accumulated best practices. Non-functional examples in docs risk obsoletion because they are not functional, tested or in production. Create examples that are tested and functional in production to ensure they are up-to-date. The general rule is add docs to functional example code, do not add broken example code to docs.

An example comprehensively demonstrates the best practices for all use cases. This is so the example can be copied to create new code then unwanted use cases can be removed. Keep examples of every common task.

Below, you will find examples of examples.

Example class

/**
 * Name classes with a noun (ExampleClass) and a verb (Demonstrator)
 */
class ExampleClassDemonstrator
{
  /**
   * Prefix constant names with the type, e.g. 'MULTIPLIER_'
   */
  const MULTIPLIER_DOUBLE = 2;
  const MULTIPLIER_TRIPLE = 3;

  /**
   * Name class instances after their type
   */
  private Output $output;
  
  /**
   * Use dependency injection with constructor injection being the first preference
   */
  public function construct(
    Output $output, // use trailing comma
  ) {
    $this->output = $output;
  }

  /**
   * Method name comes from class name, reverse the verb (demonstrate) and noun (ExampleClass)
   */
  public function demonstrateExampleClass(
    int $input1, // one argument per line
    int $input2, // use trailing comma
  ): int {
    $this->output->writeLine('Hello world');
    return ($input1 + $input2) * self::MULTIPLIER_DOUBLE; // parantheses reduce calculation errors
  }
}

Example unit test

use ExampleClassDemonstrator as Subject; // import class under test as 'Subject'

class ExampleClassDemonstratorTest // name test class after class under test
{
  private Subject $subject; // instance under test is called 'subject'
  private Output $output;

  public function setup() {
    $this->subject = new Subject(
      $this->output = mock(Output::class),
    )
  }

  public function testBasicTest () {
    // arrange
    $input1 = 2;
    $input2 = 3;
    
    // act
    $actual = this->subject->demonstrateExampleClass( // return value is called 'actual'
      $input1,
      $input2,
    );
    
    // assert
    $this->assertEquals(
      ($input1 + $input2) * 2, // demonstrate how complex values are calculated
      $actual
    );
  }
}

Example table creation

CREATE TABLE `example`
-- table names are singular, not plural
(
  `id` INT NOT NULL AUTO_INCREMENT,
  -- primary key is the first column

  `created_at` TIMESTAMP NOT NULL,
  -- created_at is the second column

  `updated_at` TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  -- updated_at is the third column

  `identifier` VARCHAR(255) CHARACTER SET utf16 COLLATE utf16_bin NOT NULL,
  -- unique string that identifies this row
  -- if used, it will be the fourth column

  `permitted_at` TIMESTAMP NOT NULL,
  -- a boolean recorded as a nullable date to show when it was set

  `found_at` TIMESTAMP,
  -- use past tense for time-related columns

  `created_by_user_id` INT,
  -- record who created this row

  PRIMARY KEY (`id`),
  FOREIGN KEY(created_by_user_id) REFERENCES user(id)
);

Example API end point

An example end point should be functional in production but should have no effect on the system when called. It demonstrates how a new end point is structured and provides an example response.

GET /example?created_at_gte=2022-12-01&is_active=1

# end points are singular, not plural, e.g. 'example' not 'examples'
GET /example

# name comparison filters with gt, gte, lt, lte
created_at_gte=2022-12-01

# use 'is_' for boolean filter names
is_active=1
{
  "status": "ok",
  "criteria": {
    "created_at_gte": "2022-12-01T00:00:00Z",
    "is_active": true
  }
  "total": 2,
  "data": [
    {},
    {}
  ]
}