REST API vs upserting and "updeleting"

Viewed 18

I am building an API with a table (I am deliberately simplifying the schema below to only focus on what is questionable) that looks like this:

CREATE TABLE IF NOT EXISTS some_table
(
    id              INTEGER GENERATED ALWAYS AS IDENTITY                                   NOT NULL PRIMARY KEY,
    user_ids        TEXT[]                                                                 NOT NULL,
    field_1         TEXT                                                                   NOT NULL,
    field_2         TEXT                                                                   NOT NULL,
    field_3         TEXT                                                                   NOT NULL,
    hash_id         TEXT GENERATED ALWAYS AS ( MD5(field_1 || field_2 || field_3)) STORED UNIQUE NOT NULL
)

The API is a bit trickier than a conventional CRUD in that:

(1) Inserting into the table depends on whether md5(field_1||field_2||field_3) already exists. If it does, I need to append the value user_id to the array field user_ids. Else, insert the row.

(2) Deleting a row also depends on the state of user_ids. Actually, my current implementation makes the database handle deletions in that there is a trigger that acts on updates and deletes rows whenever cardinality(user_ids) = 0.

CREATE OR REPLACE FUNCTION delete_row() RETURNS trigger AS
$$
BEGIN
    IF tg_op = 'UPDATE' THEN
        DELETE FROM some_table WHERE id = NEW.id;
        RETURN NULL;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER some_table_delete_row
    AFTER UPDATE
    ON some_table
    FOR EACH ROW
    WHEN (CARDINALITY(NEW.user_ids) = 0)
EXECUTE PROCEDURE delete_row();

As you can see, there is no traditional deleting. What really happens is removing items from user_ids until the length of the array is 0 and then the database will autoremove the row.

  1. I think that the PUT method is the best match for how I want to implement upserts.

  2. It's trickier with DELETE/PUT for decrementing user_ids. Ideally, that looks likes PATCH in that only one field is modified at a time and nothing is allowed to be deleted manually.

  3. Using an auto-generated hash_id value is convenient. That said, I am not sure whether it's the best option when I think of how deletes should work. The endpoint for that is base_url/items/{hash_id}, but in this case I will also need to calculate the hashed value in code or, as another option, just always pass the object in the request so that I can do WHERE hash_id = md5($field_1 || $field_2 || $field_3).

What do you think?

0 Answers
Related