Best practice for handling public and internal IDs in REST APIs using UUID and slug columns in Laravel - php

I have a table that contains a classic auto-incrementing ID and the name of the business. To avoid exposing the business ID to the client, I want to use a UUID. So far, so good. The only thing is that for calling it from the URL, it may be better to have a more user-friendly format like "api/businesses/my-business" instead of "api/businesses/10b940f2-5f8c-42ac-9c35-b6d0de45995b". Therefore, if I add a "slug" column to the table to use for GET requests, while using the UUID for data updates, would this be considered a best practice?
In my case, I need to create a record in a quotes table, and therefore the PATCH will be:
PATCH /api/quotes/4dc93692-0ad9-4131-94fe-b4afec88d037
{
"business_uuid": "10b940f2-5f8c-42ac-9c35-b6d0de45995b",
"object": "My quote object",
"another_column": "Hello",
}

If your database table structure contains id, uuid, slug, consider following:
Use id internally within backend only.
Use uuid when processing resources with REST API (CRUD).
Use slug when you want to process resources somewhere where its more easier for human to read/identify/understand data. Don't forget that slug must be unique. But for basic CRUD operations between services I would still recommend to keep using uuid.
I would also recommend to checkout Laravel docs regarding Laravel Resources which can help you to prepare data for API, and slugify helper function to process one of your data fields.

Related

Is this the right development approach in CakePHP?

I would like to know, if I am following the best practices of development in CakePHP framework.
If you have for a example an Invoices Table, and you want to display the status of the Invoice, let's say you want a green label for the status of the invoice like this:
<span class="green">Paid</span>
What i do is the following. I create a virtualfield on my model named statuslabel, in that virtualfield i call a Helper that displays an element.
so it would be Model->Helper->Element
That way anywhere in my application i can call statuslabel like it was a field from that model and i would get the statuslabel.
My big question is if this is the right way to do it or i am doing it all wrong?
You should avoid violating the MVC principles in your code, in this case specifically containing presentation logic in the model code. This equally applies to CakePHP and other MVC frameworks.
You might still go ahead and create a virtual field called status which can calculate the status of your invoice based on other entity fields. If you have the status stored in the database already as a normal entity field, then you can skip the virtual field.
The view layer is where you want all your presentation code. You can either do it directly in views, or move the logic to the helper. The appropriate function in the helper would take your status field as input and output the appropriate classes into the template based on the status value.
The advantage of keeping presentation code in the view layer (template and helper classes in CakePHP) is that it is easy to replace it later on by updating your templates. CakePHP 3 also gives you the option to create themes via plugins, which is how you can easily change the UI of your application on the fly, but only if you stick to the design principles of MVC.
Generally using virtual fields are not an bad idea. Sometimes the logic behind simple answer is quite complex that it can not be done via SQL or with reasonable amount of SQL.
It is important to remember, that most of the time, using queries directly is much faster without extra PHP processing. So for what comes to your question, if you don't have any PHP logic (besides generating SQL expressions), I would say go with it but...
...There is also point for discussion about database design.
I can't really say about your database schema behind the question, but for me such simple thing than invoice status should definitely be in database directly as and int type field. So what comes to my experience about invoicing systems, database schema could be something like:
invoices
id
invoice_status_id
invoice_statuses
id
title
If you create your model associations and query your database correctly, you end up having invoice status in query results and you can use it just like described.
Btw. most of the time, using reusable elements is good practice. Less code to maintain :D

Apigility+Doctrine: custom response

I have a project running on Apigility + Doctrine. From a scratch (automatically without writing extra code), I can retrieve entities and collections with pagination, filtering, etc.
This is perfect when retrieving DB rows, however, most services need to return much more data. For example: a to-do list where the "tasks" have parents, if you want to retrieve this like a tree, you´ll have to process it first. Very often I need flags to tell the frontend how to process data or keys to display or hide stuff. Sometimes it is useful to retrieve extra information that is not expressed in the database as FK or PK, etc.
So far, with Apigilty+Doctrine, if I want to add ANY information to the output, I have to modify the Entity, set up the correct keys, and it works. However, from the previous examples you can see that the data that I need is NOT coming from the database or I cannot simply express the relation as a DB dependency.
Questions:
What is the correct way of doing this?
Is there are documentation about this problem?
How can I customize my output keeping a correct HAL structure?
By default, the Entity values will be given as response as is. If you want to modify the value (eg: retrieving parent data, retrieving child data, or modifying the data format) you should create a Hydrator for this Entity, and custom Hydrator Strategy for this Entity value.
Here is Hydrator example from my Apigility and Doctrine project
https://github.com/aqilix/zf3-apigilty-oauth2/blob/1.0.1/module/User/src/V1/Hydrator/UserProfileHydratorFactory.php

Couchbase JSON structure model

I want to work with couchbase json-document oriented.
But I don't know what's the best way to store and structure data and retrieve it later.
Is there somehow any tutorial to get started (the learing resources on couchbase.com did not help)?
I'm using PHP to access to couchbase.
I've got the following sample:
(new document)
user1
{
"uid":1,
"name":"marius"
}
(new document)
planet1
{
"pid":1,
"user_uid":1,
"name":"earth"
}
(new document)
user2
{
"uid":2,
"name":"anyone"
}
(new document)
planet2
{
"pid":2,
"user_uid":2,
"name":"saturn"
}
Now what would be the smartest way to set (insert) these documents into the database and how can I get (select) the documents by selection.
To say it in SQL I want to -> SELECT * FROM user,planet WHERE user.uid=1 AND planet.user_uid=1
Couchbase stores data differently than a relational database.
There are two main ways to get data out of Couchbase:
Key/Value. This means you give your document one key to query on and then obviously the value is going to be the entire document. So for a user:
user = couch.get(123)
That would return the entire document for user ID 123.
Views. You can write views in Couchbase using map/reduce functions. The cool thing is that these views can be accessed in a similar way to views in CouchDB, so you can do things like ordering and limiting. http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
Check out the design documents/views in your Couchbase portal. When you write one it'll give you a URL to test your map/reduce stuff. Then you can add parameters to the URL to do additional work.
There is no general way in saying how your documents should be designed. It do depend on the characteristics of your app. Write vs Read ratio? How is the data consumed etc. With the strengths of transforming data using views in couch, I guess you could make more "generic" documents and create specific views that transform the doc to fit your use-case. Of course not a solution that you should apply to all use-cases (don't see it as the silver-bullet design).
A classic example is the blog example. Should you store comments in the post or extract comments and have the reside on their own, with a reference? It depends on the characteristics. Is it more common to have a few comments or is it usually loads of comments?
Another sample. What if you store a order document. Should the customer be part of the order or the order of the customer? Could it be both? Yes, it could. I would say that with document dbs you need to be a bit more open to duplication of data. Could it be that the Customer doc still exists as the "current view" of the customer, with all his data and the Order contains fragments of a customer snapshot; useful for the order-context and some overview in the app, which then uses references to the actual customer doc? Probably. But again, it depends on how you would consume the data.
Regarding SQL translation: http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-sql.html

PHP OOP: Providing Domain Entities with "Identity"

Bit of an abstract problem here. I'm experimenting with the Domain Model pattern, and barring my other tussles with dependencies - I need some advice on generating Identity for use in an Identity Map.
In most examples for the Data Mapper pattern I've seen (including the one outlined in this book: http://apress.com/book/view/9781590599099) - the user appears to manually set the identity for a given Domain Object using a setter:
$UserMapper = new UserMapper;
//returns a fully formed user object from record sets
$User = $UserMapper->find(1);
//returns an empty object with appropriate properties for completion
$UserBlank = $UserMapper->get();
$UserBlank->setId();
$UserBlank->setOtherProperties();
Now, I don't know if I'm reading the examples wrong - but in the first $User object, the $id property is retrieved from the data store (I'm assuming $id represents a row id). In the latter case, however, how can you set the $id for an object if it has not yet acquired one from the data store?
The problem is generating a valid "identity" for the object so that it can be maintained via an Identity Map - so generating an arbitrary integer doesn't solve it.
My current thinking is to nominate different fields for identity (i.e. email) and demanding their presence in generating blank Domain Objects. Alternatively, demanding all objects be fully formed, and using all properties as their identity...hardly efficient.
(Or alternatively, dump the Domain Model concept and return to DBAL/DAO/Transaction Scripts...which is seeming increasingly elegant compared to the ORM implementations I've seen...)
You would use the setId function if you are controlling the IDs, if you want to override the data store ID, or if you want to update/delete the data without having to retrieve it first (i.e. already have the ID from a POST).
Another alternative would be calling setId() to reserve an ID by "querying" (insert a record) the data store for the next available ID.
It's not really relevant what the ID is set to until you actually need to use it to reference something. Calling setId with no parameter would do nothing except flag the object as new data. Once you actually try to "get" the ID is when one would be generated. Sort lazy ID generation.

MySQL Status Model -- Best Implementation?

So I'm working on a framework-esque system with one of my co-workers. Our current challenge is how to best implement statuses. Oftentimes, a status will carry with it unique data (a color for a table row, or text to be displayed to a user. etc). Currently, we have a statuses table which contains all this data. Contained in that table is a column: "css_class", which, whenever a record has that status, the specified CSS class is attached to the element (in this case a tr). Also, in order to assign another record a specific status, a foreign key is specified in that database table (in this case, a user has a specific status. So in the users table, there is a statuses_id foreign key). This implementation works alright, but there are a few problems. First, what if I need to perform a specific action in PHP if a record is in a specific status? The way we do it now is something like this:
if($user->status==0)
{
//execute some code
}
This really doesn't work well if statuses can change. Change one status, and the associated code either breaks or behaves differently than intended.
The other issue, and the main reason for posting a question is that the table contains the column "css_class". This is very versatile and allows us change the style of a specific status very quickly. But we really dislike the idea of putting code inside a database. Perhaps having CSS classes in a database isn't necessarily a bad thing, but I really don't know what the common practice is. Any ideas?
EDIT:
What I've gathered from the first few answers is that I should keep all my view stuff out of my model stuff in order to maintain an MVC framework. My argument is that if I keep the css_class name out of the database, then I'm checking the status id in the view in order to decide which class to assign it. So if I put the class in the database, I'm putting View information in the Model. If I don't put CSS classes in the database then I'm putting Model information in the View (checking which ID it belongs to). So by not muddying up the Model, I muddy up the view instead.......
The most elegant way I've seen this solved so far (and I've worked with a few MVC implementations now) is to store only the relevant data in the database. E.g. you'd store status="red" in the database, and leave it up to the view to know what to do with a red status, in terms of CSS. The problem is then solved by designing a sufficiently advanced View layer that creates reusable structures -- that way you don't need to always be updating things on a page-by-page basis when the css changes.
Passing this information up to the Model somewhat defeats the point of the content/presentation separation, because now your code needs to know to pull presentation information off the database and forward it along to the View level or, shudder, you'll be pulling that stuff from the database right in your View layer code, which makes maintenance a nightmare, as you've now lost control over the information flow.
If you want to continue your paradigm of storing this in the DB, you could make another table that maps VARCHAR names of the statuses to their corresponding INTEGER IDs.
However, if this was my framework. I would not be storing view information like this in the database. This would be handled by the V of my MVC setup.
From a data modelling point of view:
Have a different table for each "kind" of status; keep user statuses separate from page statuses (for example) - group the like entities together.
Don't put the CSS classes into the database, but use some form of status indicator - this could be an ENUM column, if you know the set of possible statuses up front. Transform this into the appropriate CSS class in the view layer. You don't want to end up in a situation where your CSS can't be changed because some data in the database prevents it.

Categories