@megacookie/postgraphile-plugin-nested-mutations
This plugin implements nested mutations based on both forward and reverse foreign key relationships in PostGraphile v4. Nested mutations can be of infinite depth.
My version adds (batch) creating and upserting features using upsert
, batchCreate
, batchUpsert
and allows you
to deleteOthers
, to delete existing rows (resulting replacing the rows the existing rows with the new rows that you
want to insert)
Getting Started
CLI
postgraphile --append-plugins @megacookie/postgraphile-plugin-nested-mutations
or just add this to schemaPlugins in your config file if you're using Postgraphile in library mode.
See here for more information about loading plugins with PostGraphile.
Library
const express = require('express');
const { postgraphile } = require('postgraphile');
const PostGraphileNestedMutations = require('postgraphile-plugin-nested-mutations');
const app = express();
app.use(
postgraphile(pgConfig, schema, {
appendPlugins: [
PostGraphileNestedMutations,
],
})
);
app.listen(5000);
Plugin Options
When using PostGraphile as a library, the following plugin options can be passed
via graphileBuildOptions
:
nestedMutationsSimpleFieldNames
Use simple field names for nested mutations. Instead of names suffixed with
tableBy<Key>
and tableUsing<Key>
, tables with a single foreign key relationship
between them will have their nested relation fields named table
. Defaults to
false
.
postgraphile(pgConfig, schema, {
graphileBuildOptions: {
nestedMutationsSimpleFieldNames: true,
}
});
nestedMutationsDeleteOthers
Controls whether the deleteOthers
field is available on nested mutations. Defaults
to true
.
postgraphile(pgConfig, schema, {
graphileBuildOptions: {
nestedMutationsDeleteOthers: false,
}
});
nestedMutationsOldUniqueFields
If enabled, plural names for one-to-one relations will be used. For backwards
compatibility. Defaults to false
.
postgraphile(pgConfig, schema, {
graphileBuildOptions: {
nestedMutationsOldUniqueFields: false,
}
});
Usage
This plugin creates an additional field on each GraphQL Input
type for every forward
and reverse foreign key relationship on a table, with the same name as the foreign table.
Each nested mutation field will have the following fields. They will accept an array if the relationship is a one-to-many relationship, or a single input if they are one-to-one.
Connect to Existing Record
connectByNodeId
Connect using a nodeId
from the nested table.
connectBy<K>
Connect using any readable primary key or unique constraint on the nested table.
Creating New Records
create
Create a new record in the nested table.
Delete existing Record
deleteByNodeId
Delete using a nodeId
from the nested table.
deleteBy<K>
Delete using any readable primary key or unique constraint on the nested table.
Updating Records
updateByNodeId
Update a record using a nodeId
from the nested table.
updatedBy<K>
Update a record using any readable primary key or unique constraint on the nested table.
Example
create table parent (
id serial primary key,
name text not null
);
create table child (
id serial primary key,
parent_id integer,
name text not null,
constraint child_parent_fkey foreign key (parent_id)
references p.parent (id)
);
A nested mutation against this schema, using Parent
as the base mutation
would look like this:
mutation {
createParent(input: {
parent: {
name: "Parent 1"
childrenUsingId: {
connectById: [{
id: 1
}]
create: [{
name: "Child 1"
}, {
name: "Child 2"
}]
}
}
}) {
parent {
id
name
childrenByParentId {
nodes {
id
name
}
}
}
}
}
Or using Child
as the base mutation:
mutation {
createChild(input: {
child: {
name: "Child 1"
parentToParentId: {
create: {
name: "Parent of Child 1"
}
}
},
}) {
child {
id
name
parentByParentId {
id
name
}
}
}
}
Smart Comments
Smart comments are supported for renaming the nested mutation fields.
comment on constraint child_parent_fkey on child is
E'@fieldName parent\n@foreignFieldName children';