Directus

Directus adapts to an existing DB Schema, adding a few meta tables but not changing the original tables. Relations and stuff is easily possible and quite powerful.

Docs

2021-08-17 – with Version 9.x, Directus is a Node.js app, with a Laravel version in the pipeline.

Version 8.x is the last working PHP version of Directus.

Official 8.x Docs

Using Spatial Field Types in Directus

In a project I used Spatial Field Types and Directus couldn't handle them, even if it offers a map field type.

Unfortunately, Directus 8.x throws an error trying to save a data to a table with unsupported fields (I don't know why it's not just ignored).

In order to keep using the native spatial types I had to add additional lat,lang fields as text and create a trigger in the MySQL DB, that writes the spatial fields on any Insert or Update operation to another table that holds the spatial data.


CREATE TRIGGER `places_after_insert` AFTER INSERT ON `places` FOR EACH ROW BEGIN
#Update coords table
INSERT INTO places_coords (id,coords) VALUES (NEW.id,POINT(new.lng,new.lat)) ON DUPLICATE KEY UPDATE coords=POINT(new.lng,new.lat);
END

And the same for when a row is updated.


CREATE TRIGGER `places_after_update` AFTER UPDATE ON `places` FOR EACH ROW BEGIN
#Update coords table
INSERT INTO places_coords (id,coords) VALUES (NEW.id,POINT(new.lng,new.lat)) ON DUPLICATE KEY UPDATE coords=POINT(new.lng,new.lat);
END

It's easy enough to use JOIN those two tables.

In my app I can use my SQL Queries or even better I can use mevdschee/php-crud-api: Single file PHP script that adds a REST API to a SQL database if I don't want to use the Directus API because it comes with a geojson controller, and so I can use my geo data in the correct format right away.

Extending Directus User Table

open https://website/admin/#/:project/settings/collections/directus_users

https://github.com/directus/directus/issues/2274#issuecomment-586374271

Using Custom User Table

See https://github.com/directus/directus/discussions/7468

I want to verify a user of my app, against a list of users, stored and administered in Directus. Initially, I wanted to use directus_users table and the POST /:project/auth/authenticate endpoint, but it seems weird to mix Directus users with this third party user table.

The docs say:

Users vs. Directus Users Because it comes with auth, permissions, and other features out-of-the-box, many developers want to repurpose Directus Users to manage “users” within their proprietary client application. While this may work in some projects, we recommend creating your own users' collection to avoid issues.

https://v8.docs.directus.io/guides/modules.html#user-directory

So I created a new collection called members, with a text field for the unique username/email and a password field.

After reading the docs up and down and search the old issues, I came up with this strategy to verify a user via the API (using the access_token of the Directus Admin):

GET {{url}}/:project/items/members?single=1&filter[email][eq]=test@example.com

{
    "data": {
        "id": 2,
        "status": "published",
        "sort": null,
        "owner": 1,
        "created_on": "2021-08-17T16:43:54+00:00",
        "modified_on": "2021-08-17T16:43:54+00:00",
        "notice": null,
        "test": null,
        "email": "test@example.com",
        "password": "$2y$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    "public": true
}

And in a second step I would post the hash along with the password

POST {{url}}/:project/utils/hash/match

https://v8.docs.directus.io/api/utilities.html#verify-a-hashed-string

Body:

{
  "hash": "$2y$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "string": "123456"
}

Result:

{
    "data": {
        "valid": true
    },
    "public": true
}

Is that the way to do it? I found it nowhere documented. Is there a better way, with just one call?

Extending Directus

Extension Interfaces are possible in Vue

Field Types

API

GET /:project/items/:collection?fields=*,all_relational_fields.*,specific.field
GET /:project/items/:collection/:id
# Get all top-level fields
?fields=*

# Get all top-level fields and all second-level relational fields
?fields=*.*

# Get all top-level fields and second-level relational fields within images
?fields=*,images.*

# Get only the first_name and last_name fields
?fields=first_name,last_name

# Get all top-level and second-level relational fields, and third-level fields within images.thumbnails
?fields=*.*,images.thumbnails.*

Downside: https://github.com/directus/v8-archive/issues/1190