A package to prefix ids in a Laravel app

Original – by Freek Van der Herten – 4 minute read

We've released a new package called spatie/laravel-prefixed-ids. In this post, I'd like to tell you all about it.

Why prefix ids

When thinking of companies with excellent APIs, Stripe is one of the first that comes to mind. They have excellent docs, and it seems like they have polished every detail to make sure the developer experience is just right.

One of the details they took care of is prefixing all of their ids. Here's an example: when creating a token to interact with their API, you'll notice that that token is prefixed. Let's take a look at such a token:

sk_test_FKdleMEKfiemsiDSMEODL

In the example above, the sk stands for "secret key", and test signifies that this token is meant to be used in Stripe's test environment. Without that prefix, the value would just be a random string of which you'd have to guess what it is.

In fact, Stripe prefixes almost all of their ids. In my mind, this is a great little detail.

Prefixing ids in a Laravel app

The spatie/laravel-prefixed-ids can automatically generate prefixed ids in a Laravel app. It offers handy methods to retrieve Eloquent models using those prefixed ids.

You can install the package via Composer. No surprises there.

composer require spatie/laravel-prefixed-ids

On each model that needs a prefixed id, you should use the Spatie\PrefixedIds\Models\Concerns\HasPrefixedId trait.

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Spatie\PrefixedIds\Models\Concerns\HasPrefixedId;

class YourModel extends Model
{
    use HasPrefixedId;
}

You'll need to write a migration to add a prefixed_id column to its underlying table.

If you wish to use another attribute name, you should publish the config file (see below) and set the prefixed_id_attribute_name config value to the attribute name of your liking.

Schema::create('your_models_table', function (Blueprint $table) {
   $table->string('prefixed_id')->index();
});

To register your models, you should pass the desired prefix and your model's class name to PrefixedIds::registerModels.

Spatie\PrefixedIds\PrefixedIds::registerModels([
    'your_prefix_' => YourModel::class,
    'another_prefix' => AnotherModel::class,
]);

Typically, you would put the code above in a service provider.

With this in place, when a model is created, it will automatically have a unique, prefixed id in the prefixed_id attribute.

$model = YourModel::create();
$model->prefixed_id // returns a random id like `your_model_fekjlmsme39dmMS`

You can find the model with a given prefix by calling findByPrefixedId on it.

YourModel::findByPrefixedId('your_model_fekjlmsme39dmMS'); // returns an instance of `YourModel`
YourModel::findByPrefixedId('non-existing-id'); // returns null

You can call find on Spatie\PrefixedIds\PrefixedIds to automatically get the right model for any given prefixed id.

$yourModel = Spatie\PrefixedIds\PrefixedIds::find('your_model_fekjlmsme39dmMS'); // returns an instance of `YourModel` or `null`
$otherModel = Spatie\PrefixedIds\PrefixedIds::find('other_model_3Fjmmfsmls'); // returns an instance of `OtherModel` or `null`

To use the prefixed ids in your routes, you'll have to add the getRouteKeyName method to your model. It should return the name of the attribute that holds the prefixed id.

public function getRouteKeyName()
{
    return 'prefixed_id';
}

With this in place a route defined as...

Route::get('your-model/{yourModel}', YourModelController::class)`

... can be invoked with an URL like "/your-model/your_model_fekjlmsme39dmMS".

You'll find more info on route model binding in the Laravel docs.

In closing

When creating an API, consider using prefixed ids. The consumers of your API will probably much appreciate this.

spatie/laravel-prefixed-ids isn't the first package our team has created. Be sure to take a look at this list of PHP and Laravel packages our team has created previously.

Stay up to date with all things Laravel, PHP, and JavaScript.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

Webmentions

Oilmone liked on 25th February 2021
ArielMejiaDev liked on 25th February 2021
Ahmed Shahawi liked on 25th February 2021
Ahh, useability tweak for APIs! Great idea.
Chris Oliver liked on 25th February 2021
Claudio_Pereira liked on 25th February 2021
Matt Murtaugh liked on 25th February 2021
Albert Suntic liked on 25th February 2021
Vaggelis Yfantis liked on 25th February 2021
Anne Koepcke retweeted on 25th February 2021
Sadegh 🐘 liked on 25th February 2021
Anne Koepcke liked on 25th February 2021
Peter Brinck 🀘 liked on 25th February 2021
Marijn Bent liked on 25th February 2021
Jagruti Metaliya liked on 25th February 2021
Patrick Brouwers liked on 25th February 2021
Podcaster Dev liked on 25th February 2021
Boris DEHOUMON liked on 25th February 2021
Sheldon Kotyk retweeted on 25th February 2021
Le Huu Phuc liked on 25th February 2021
Ken V. liked on 25th February 2021
Wanjala Joel liked on 25th February 2021
Laravel tweets πŸ€– liked on 25th February 2021
Laravel tweets πŸ€– retweeted on 25th February 2021
PHP Synopsis retweeted on 25th February 2021
Mark Topper liked on 25th February 2021
Fayçal EL MAKOUDI liked on 25th February 2021
Robin Dirksen liked on 25th February 2021