blablabla1234678 / REST

REST API and client with HATEOAS
0 stars 0 forks source link

Support request headers by hyperlinks #14

Open blablabla1234678 opened 1 month ago

blablabla1234678 commented 1 month ago

My old dream to use mongodb _id-s for cache etagging. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag https://orangematter.solarwinds.com/2019/12/22/what-is-mongodbs-id-field-and-how-to-use-it/ I want to think it through how to support this with a REST service. In general this means resource versioning.

blablabla1234678 commented 4 weeks ago

Mongodb has a _id UUID which could be used in Etag. Etag is relative easy to understand, it is a version identifier of a resource. We can use if-match for POST, PUT, DELETE, PATCH and it will give 422 if the latest version is not matching the etag. We can use if-none-match for GET and the server returns 304 not modified if the resource has not changed since we grabbed the etag from the last request. So it is pretty useful. Though how do we know the etags to send?

blablabla1234678 commented 4 weeks ago

We need to send the etags in the response. We can either send an etag header or include them into the body of the response. The first is the standard way. The only problem that we can have nested resources something like the following:

GET /a/123

{
    items: {
        b: {
            items: {c: 1, d:3},
            hyperlinks: {
                self: {
                    type: "readB",
                    id: 456
                }
            }
        }
    },
    hyperlinks: {
        self: {
            type: "readA",
            id: 123
        }
    }
}
blablabla1234678 commented 4 weeks ago

Here we have two options.

blablabla1234678 commented 4 weeks ago
{
    version: "sdghkg4352asgreh",
    items: {
        b: {
            version: "adg235hdfhg46a",
            items: {c: 1, d:3},
            hyperlinks: {
                self: {
                    type: "readB",
                    id: 456
                },
                edit: {
                    type: "updateB",
                    id: 456,
                    c: 1,
                    d: 3
                },
            }
        }
    },
    hyperlinks: {
        self: {
            type: "readA",
            id: 123
        }
    }
}
blablabla1234678 commented 4 weeks ago

Another option is adding the version to each of the hyperlinks:

{
    items: {
        b: {
            items: {c: 1, d:3},
            hyperlinks: {
                self: {
                    version: "adg235hdfhg46a",
                    type: "readB",
                    id: 456
                },
                edit: {
                    version: "adg235hdfhg46a",
                    type: "updateB",
                    id: 456,
                    c: 1,
                    d: 3
                },
            }
        }
    },
    hyperlinks: {
        self: {
            version: "sdghkg4352asgreh",
            type: "readA",
            id: 123
        }
    }
}
blablabla1234678 commented 4 weeks ago

I might prefer using the hyperlinks header part and send explicitly if-match. Since this is a general solution for headers I think the name of the issue can be changed.

blablabla1234678 commented 4 weeks ago

Maybe using FlatObject for requests is not a good idea after all because it is hard to add additional metadata like headers.