Mutate

Introduction

Laravel Rest Api exposes the mutate endpoint which is dedicated to modify/create data for your frontend users.

Usage

Here is a quick look at what you can do:

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "create",
            "attributes": {"name": "test", "email": "uniq4@uniq.fr", "password": "hidden"},
            "relations": {
                "star": {
                    "operation": "create",
                    "attributes": {"number": 2}
                }
            }
        },
        {
            "operation": "create",
            "attributes": {"name": "test2", "email": "uniq5@uniq.fr", "password": "hidden"},
            "relations": {
                "star": {
                    "operation": "attach",
                    "key": 1
                }
            }
        },
        {
            "operation": "update",
            "key": 2,
            "attributes": {},
            "relations": {
                "star": {
                    "operation": "detach",
                    "key": 1
                }
            }
        },
        {
            "operation": "create",
            "attributes": {"name": "test2", "email": "uniq6@uniq.fr", "password": "hidden"},
            "relations": {
                "posts": [
                    {
                        "operation": "sync", 
                        "without_detaching": true,
                        "key": 1,
                        "attributes": {"number": 4},
                        "pivot": {"color": "#2271B3"}
                    },
                    {
                        "operation": "toggle",
                        "key": 2,
                        "attributes": {"number": 4},
                        "pivot": {"color": "#C51D34"}
                    }
                ]
            }
        },
        {
            "operation": "update",
            "key": 1,
            "attributes": {"name": "new name :)"},
            "relations": {
                "posts": [
                    {
                        "operation": "create",
                        "attributes": {},
                        "relations": {
                            "star": {
                                "operation": "create",
                                "attributes": {"number": 2}
                            }
                        }
                    },
                    {
                        "operation": "detach",
                        "key": 2
                    }
                ]
            }
        }
    ]
}

Keep in mind that all fields specified here must be defined in the fields method of your resource first.

Specifications

KeyTypeRequiredDefaultDescription
operationstringxThe type of operation you want to achieve
attributesstringxThe attributes for the creation
keymixedWhen operation is attach, detach, update, toggle or syncThe model identifier
without_detachingbooleanfalseSpecify if sync should detach
relationsarrayThe model relations you want to access

Response

As a response you'll receive the keys of the models that were impacted, grouped by created or updated.

{
  "created": [
    72979
  ],
  "updated": []
}

Create

To indicate that you want to create a resource you must use the "create" operation:

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "create",
            "attributes": {"name": "Gautier Deleglise", "email": "gautier@mail.com", "password": "password"}
        },
        {
            "operation": "create",
            "attributes": {"name": "My other user", "email": "him@mail.com", "password": "password"}
        }
    ]
}

Update

To indicate that you want to update a resource you must use the "update" operation. This also means you have to specify the entry you want to modify with the "key" key.

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "attributes": {"name": "new name"},
        },
        {
            "operation": "update",
            "key": 2,
            "attributes": {"name": "other name"},
        },
    ]
}

Relations

In order to make the Api more flexible, Laravel Rest Api allows the user to modify / create / attach / detach distant relations with a single call.

You'll need to specify the relations key as follows:

Create

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "relations": {
                "posts": [
                    {
                        "operation": "create",
                        "attributes": { "title": "My Post" },
                        "relations": {
                            "star": {
                                "operation": "create",
                                "attributes": {"number": 2}
                            }
                        }
                    },
                ]
            }
        }
    ]
}

Update

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "relations": {
                "posts": [
                    {
                        "operation": "update",
                        "key": 1,
                        "attributes": { "title": "My Post" },
                        "relations": {
                            "star": {
                                "operation": "update",
                                "key": 1,
                                "attributes": {"number": 2}
                            }
                        }
                    },
                ]
            }
        }
    ]
}

Attach

For the attach operation you only need to specify the related key.

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "relations": {
                "posts": [
                    {
                        "operation": "attach",
                        "key": 5
                        "relations": {
                            "star": {
                                "operation": "attach",
                                "key": 5
                            }
                        }
                    },
                ]
            }
        }
    ]
}

Detach

For the detach operation you only need to specify the related key.

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "relations": {
                "posts": [
                    {
                        "operation": "detach",
                        "key": 1,
                        "relations": {
                            "star": {
                                "operation": "detach",
                                "key": 1
                            }
                        }
                    }
                ]
            }
        }
    ]
}

Sync

For the sync operation you only need to specify the related key. You also can specify if you want the sync operation to detach already related records.

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "relations": {
                "posts": [
                    {
                        "operation": "sync",
                        "without_detaching": true,
                        "key": 1,
                        "relations": {
                            "star": {
                                "operation": "detach",
                                "key": 1
                            }
                        }
                    }
                ]
            }
        }
    ]
}

Toggle

For the toggle operation you only need to specify the related key.

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "relations": {
                "posts": [
                    {
                        "operation": "toggle",
                        "key": 1,
                        "relations": {
                            "star": {
                                "operation": "detach",
                                "key": 1
                            }
                        }
                    }
                ]
            }
        }
    ]
}

Morph to relation

Since you can only specify one resource in Laravel Rest Api, your relation always point to a model. You don't need to specify it.

// (POST) api/tags/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "relations": {
                "taggable": [
                    {
                        "operation": "attach",
                        "key": 1
                    }
                ]
            }
        }
    ]
}

The type you specify is the Resource. Laravel Rest Api will automatically take the model linked to the resource to create your entry. This allows you to have multiple resources with the same model.

Pivot creation

In some cases, when you are dealing with a relation that has a pivot, you might want to fill it. You can do this by specifying the "pivot" key:

// (POST) api/users/mutate
{
    "mutate": [
        {
            "operation": "update",
            "key": 1,
            "relations": {
                "posts": [
                    {
                        "operation": "create",
                        "attributes": { "title": "My super post" }
                        "pivot": { "number": 20 }
                    },
                ]
            }
        }
    ]
}
  The relation pivot fields must be declared in your resource.