Laravel: UUID for public, ID for the application

Okay, there is one way.

Setting up the DatabaseSome databases can be configured to set an UUID into the primary key when inserting a new row.

You should check this on whatever RDBMS are you using, since implementation vary between each of them.

You can also tell your application to set a default UUID when creating a new record using the creating Eloquent event, but that will leave you using Eloquent for everything.

If you insert a record directly to the database, you may get an error — one of the reasons why I prefer to set automatic UUIDs inside the Database instead of the application; it shouldn’t depend on anything since is a Database behaviour.

Anyway, you should set your database using Laravel like this:As you can see, we have added a $table->uuid('uuid')->index().

This code tells Laravel to use an UUID column (if supported, or use a string column), and create an index on it so the row can be quickly retrieved by its UUID, like you would when somebody access to this URL:https://podcast.

app/podcast/535c4cdf-70a0-4615-82f2-443e95c86aecYou may argue that having another index would hinder inserting operations, but is a trade off.

Now, the problem lies with the Controller and the Model.

Wiring the Model to the UUIDYou don’t have to do anything in the Model, except for two things: hide the ID from serialization, and allow the Model to be “url-routable” using the UUID.

To hide the ID, we can just push the id column into the hidden attributes.

When the Model is serialized, like when it transforms to an array or a JSON string, the ID won’t be shown.

Of course, you can access the ID getting the attribute directly like a property or array key.

The next step is to tell Laravel that, when the URL contains the UUID of the Model, get that model by the uuid column.

This will allow to find the model by setting a route, likeRoute::get({podcast}, 'PodcastController@show');and then using it in our PodcastController class.

/** * Show the Podcast by its UUID * * @param AppPodcast $podcast * @return IlluminateHttpResponse/* public function show(Podcast $podcast){ return response()->view('response', [ 'podcast' => $podcast ]);}You can also play with the resolveRouteBinding() method in your Model, were you can programatically set how to retrieve the model by the value it’s given.

You could even allow authenticated administrators to pull the record by its ID or UUID.

And that’s all.

Nothing more to do.

This technique also allows to set an UUID after your application is production.


. More details

Leave a Reply