-
Notifications
You must be signed in to change notification settings - Fork 890
Description
When dealing with related/dependent resources, I think it would be useful to "create or update" and/or "find or create" certain records.
Say for example you have some type of post
resource that can have tag
resources associated with it.
If I know that all the tag
s in the request exist, I can do this
POST /api/posts
{
"data": {
"type": "post",
"attributes": {
"title": "foo",
"body": "bar"
},
"relationships": {
"tags": {
"data": [
{ "id": "tech", "type": "tag" },
{ "id": "api", "type": "tag" }
]
}
}
}
}
If I know that all the tags are new, I can do this
{
"atomic:operations": [
{
"op": "add",
"data": {
"type": "tag",
"lid": "tech",
"attributes": {
"text": "tech"
}
}
},
{
"op": "add",
"data": {
"type": "tag",
"lid": "api",
"attributes": {
"text": "api"
}
}
},
{
"op": "add",
"data": {
"type": "post",
"lid": "new-post-1",
"attributes": {
"title": "foo",
"body": "bar"
},
"relationships": {
"tags": {
"data": [
{ "lid": "tech", "type": "tag" },
{ "lid": "api", "type": "tag" }
]
}
}
}
}
]
}
But if I don't know about the existence of these tags prior the creation of the post, I would need to first do a GET
and attempt to fetch these tags. However, since there's pretty logical/predictable defaults for this tag
resource, it doesn't seem like this GET
should be necessary.
My thought would be to add find_or_create
and create_or_update
operations and add a find_by
member.
{
"op": "find_or_create",
"find_by": ["text"],
"data": {
"lid": "tech",
"type": "tag",
"attributes": { "text": "tech" }
}
}
find_by
would accept an array of attributes that define a composite key and use the values specified in attributes
to make that query. before attempting to create the record.
May also be reasonable to also accept lid
instead of an array of attributes and attempt to match an existing resource id
to the specified lid
{
"op": "find_or_create",
"find_by": "lid",
"data": {
"lid": "tech",
"type": "tag",
"attributes": { "text": "tech" }
}:
}