Skip to content

Smart Public IDs ​

v1.2.0

Laravel Domain Generator automatically generates human-readable public identifiers for every Model using the HasHash trait.

Instead of exposing sequential IDs or long UUIDs in your API, the package creates short, readable and secure identifiers.

Smart Public IDs are generated automatically. No additional logic is required in your Models.


How it works ​

The database continues using the internal id as the primary key.

The API uses the hash column instead.

ColumnPurpose
idInternal primary key
hashPublic API identifier

Example stored in the database.

idhash
1PAT_K7XM4Q2R
2PAT_J8L4M7XP

Automatic prefixes ​

The prefix is generated dynamically from the Model name.

ModelResult
PatientPAT_K7XM4Q2R
ProductPRO_J8N4W6XM
OrganizationORG_A7KM9Q2R
MedicalRecordMRE_R6X3K8QP
UserSessionTokenUST_T9L2P7WK

Rules:

  • Single-word models use the first three letters.
  • Multi-word models generate an intelligent acronym.
  • The random code avoids ambiguous characters.

Migration ​

After generating a domain, update the migration before running it.

php
Schema::create('patients', function (Blueprint $table) {

    $table->id();

    $table->string('hash', 20)
        ->unique()
        ->index();

    $table->timestamps();
    $table->softDeletes();
});

The current format fits comfortably within 20 characters.

text
PAT_K7XM4Q2R

Generated Model ​

The package automatically generates a Model similar to this.

php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Domain\DomainGenerator\Traits\HasHash;

class Patient extends Model
{
    use HasFactory;
    use HasHash;

    protected $table = 'patients';

    protected string $hashPrefix = 'PAT';

    protected $fillable = [
        //
    ];
}

Route Model Binding ​

The HasHash trait automatically changes Laravel's Route Model Binding.

text
GET /api/patients/PAT_K7XM4Q2R

No controller changes are required.


Creating a record ​

POST /api/patients

Request.

json
{
  "name": "John Doe",
  "cpf": "12345678901"
}

Response.

json
{
  "type": "success",
  "status": 201,
  "data": {
    "hash": "PAT_K7XM4Q2R",
    "name": "John Doe"
  }
}

Listing records ​

GET /api/patients

Response.

json
{
  "data": [
    {
      "hash": "PAT_K7XM4Q2R",
      "name": "John Doe"
    },
    {
      "hash": "PAT_J8L4M7XP",
      "name": "Jane Doe"
    }
  ]
}

Finding a record ​

GET /api/patients/PAT_K7XM4Q2R

Response.

json
{
  "type": "success",
  "status": 200,
  "data": {
    "hash": "PAT_K7XM4Q2R",
    "name": "John Doe"
  }
}

Updating a record ​

PUT /api/patients/PAT_K7XM4Q2R

Request.

json
{
  "phone": "11999999999"
}

Response.

json
{
  "type": "success",
  "status": 200,
  "data": {
    "hash": "PAT_K7XM4Q2R",
    "phone": "11999999999"
  }
}

Deleting a record ​

DELETE /api/patients/PAT_K7XM4Q2R

Response.

json
{
  "type": "success",
  "status": 200,
  "message": "Record deleted successfully."
}

Internal flow ​

text
Patient::create(...)
        │
        ▼
HasHash::creating()
        │
        ▼
PublicIdGenerator
        │
        ▼
PAT_K7XM4Q2R
        │
        ▼
Database

The generated identifier provides billions of possible combinations while the UNIQUE database constraint guarantees integrity.

Smart Public IDs provide cleaner APIs, hide internal IDs and deliver a developer experience similar to Stripe and GitHub.

Released under the MIT License.