Skip to content

Latest commit

 

History

History
137 lines (95 loc) · 4.35 KB

basic-documenting-project.md

File metadata and controls

137 lines (95 loc) · 4.35 KB

Documenting Project

Writing ReadMe

Project should always contain a "README.md" file, which provides the basic documentation about it. It should provide instructions about project requirements, such as PHP version, DBMS (MySQL, PostgreSQL or else) and so on.

If project interacts with any external API, they should be mentioned along with instructions, where to get the access key for them. See "Braintree" section for example.

ReadMe file should also contain at least several sentences of project business logic description. For example:

  • "Project is a eCommerce platform, which deals with electronics..."
  • "Project is a social network for the hunters..."
  • "Project is a rental system, which deals with paper books..."

PHPDoc

"PHPDoc" can be also called "Doc comments". It serves several purposes:

  • Documenting the project, its internal logic and twists
  • Provide IDE autocomplete support
  • Provide support for code static analysis

Config Files

See config/telescope.php. It is hard to figure out config purpose by its filename only. For example: what does 'telescope' mean? Are we watching the stars here? Config for external extensions should at least contain a link to its official docs.

General Classes

See App\Http\Resources\UserResource for a bad example. If you can not provide any useful info in the PHPDoc - it is better not to write them at all. If project is filled with useless comments, you develop a habit of ignoring them.

See App\Services\Payment\Braintree for a good example. For the external service PHPDoc should always provide a links to its official documentation, sandbox etc.

It is recommended to always use a full qualified name of the class inside PHPDoc, e.g. use \Illuminate\Support\Collection instead of simply Collection. In this way you will avoid unnecessary use statements and avoid troubles during refactoring in case you move class across directory structure.

Active Record

See App\Models\User.

Each model should provide at least a single sentence about its meaning, even if it seems obsolete. For example model name User is too abstract: which user is this - a customer or an administrator? Names like Invoice, Item, Category and so on can lead to confusion.

The basic project description in ReadMe provides main direction for your thoughts, while PHPDoc at the particular class will complete it.

See barryvdh/laravel-ide-helper.

It is better to keep PHPDoc inside the models source files instead of generated by the helper. It is enough to define PHPDoc for the query() method to get all necessary autocomplete during model querying:

use Illuminate\Database\Eloquent\Model;

/**
 * User represents system customer.
 *
 * @property int $id
 * @property string $email
 * ...
 *
 * @method static \Illuminate\Database\Eloquent\Builder|static query()
 */
class User extends Model
{
    // ...
}

$user = User::query()
    ->where('name', 'John')
    ->orderBy('id', 'desc')
    ->first();

echo $user->email;

It is better to always use query() method for the "select" statement composition.

You can use following command to generate PHPDoc:

php artisan ide-helper:models

but you need to extract it from there and save in actual model's file.

JSON Resources

See App\Http\Resources\BookResource. It is better to define PHPDoc for $resource property and use long access $this-resource->id.

Inherit Doc

Always use tag @inheritdoc for all overridden fields and methods. This indicates that particular field or method declaration is provided by the parent class and redeclared to satisfy it. Absence of the @inheritdoc clearly indicates that particular entity was created for the dedicated purpose. See App\Models\User for example.

View Files

Provide link to controller. Document plain variables.

@php
/** @see App\Http\Controllers\BookController::index() */
/** @var App\Models\Book[]|Illuminate\Contracts\Pagination\LengthAwarePaginator $books */
@endphp
<div>
    @foreach ($books as $book)
    <div class="book">
        {{ $book->name }}
    </div>
    @endforeach
    {{ $books->links() }}
</div>