DEV Community

Cover image for Your Mermaid diagram is a valid input for a Laravel API generator
Loic Aron Mbassi Ewolo
Loic Aron Mbassi Ewolo

Posted on

Your Mermaid diagram is a valid input for a Laravel API generator

Data models get designed in diagrams and implemented in code, and the two drift apart from day one. The diagram in your README says Post belongsTo Category; the code says otherwise; nobody notices until a migration fails.

The fix I landed on for laravel-api-generator: make the diagram the input. Two formats work, YAML and Mermaid.

YAML

# api-schema.yaml
options:
  pest: true
  postman: true

entities:
  Category:
    fields:
      name: string unique
    relations:
      posts: hasMany Post

  Post:
    fields:
      title: string
      content: text
      status: enum(draft,published) default=draft
      published_at: datetime nullable
Enter fullscreen mode Exit fullscreen mode
php artisan make:fullapi --schema=api-schema.yaml
Enter fullscreen mode Exit fullscreen mode

Look at what's missing: Post never declares belongsTo Category, and there's no category_id field anywhere. The generator synthesizes the inverse relation and its foreign key column. You declare one side, like you would explain it to a colleague, and both sides exist in the code.

The enum line generates the backed enum class, the model cast, Rule::enum validation and a factory that picks random cases. I wrote about that chain in more detail in part 1.

This is the one I use most, because GitHub renders it in the PR:

mermaid diagram

Mermaid

php artisan make:fullapi --mermaid=docs/erd.mmd
Enter fullscreen mode Exit fullscreen mode

Both erDiagram and classDiagram work. Cardinalities map to the right Eloquent relations, UK markers become unique fields, a deleted_at column enables soft deletes. Markdown fences and comments are stripped, so a diagram pasted straight from an AI chat works as-is. Review the diagram in the pull request, merge, generate. No drift, because there's nothing to drift from.

The VS Code extension takes the same Mermaid input without the terminal, and it draws the reverse view too: an interactive diagram of your entities (zoom, pan) inside the editor. The diagram goes in, the API comes out, and the canvas shows you what actually exists.

[VISUEL 15 (fichier 13) : vraie capture du diagramme interactif de l'extension, habillée]

[VISUEL 10 (fichier 13) : split-screen diagramme Mermaid rendu / arborescence générée]

Custom primary keys propagate

Country:
  fields:
    code: string primary
    name: string
  relations:
    cities: hasMany City
Enter fullscreen mode Exit fullscreen mode

This was the request that took me the longest in v3.6. City gets a country_code column typed like the key, ->references('code') in the migration, exists:countries,code in validation, and the model declares $primaryKey, $incrementing and $keyType. The generated tests use getKey() so the same suite passes with either key style. Polymorphic relations (morphTo, morphOne, morphMany) are supported in schemas too.

Day 30

Every scaffolder demos well on day 1 and gets deleted on day 30, because regenerating would wipe your manual work. So regeneration isn't the evolution path here. Patching is:

php artisan make:fullapi Post --add-fields="excerpt:text,seo_title:string"
Enter fullscreen mode Exit fullscreen mode

This writes an incremental Schema::table migration with a down(), and patches $fillable, the casts, the PHPDoc, the validation rules, the factory and the resource in place. Your custom methods are not touched. Fields that already exist are skipped. The DTO and the tests are deliberately left alone and reported as manual follow-ups, because guessing there felt more dangerous than useful.

Practical notes

Dev dependency, MIT, generated code has no reference to the package. Works in CI and with AI coding agents; one YAML file describing the whole API turns out to be a much better target for an agent than "create twelve files". The extension mentioned above also adds a form builder with live preview, imports from a database or an OpenAPI spec, and one-click migrate, seed and docs.

If you have opinions about what a schema format should support, the issues are open. Mine changed three times while building this.

Top comments (0)