@graphile/simplify-inflection v8.0.0-beta.6
@graphile/simplify-inflection
This preset simplifies field names in the PostGraphile schema; e.g. allUsers
becomes simply users, User.postsByAuthorId becomes simply User.posts, and
Post.userByAuthorId becomes simply Post.author.
Adding this preset to your schema is almost certainly a breaking change, so do it before you ship anything!
This preset is recommended for all PostGraphile users. The main reason this preset is not enabled by default is because it increases the risk of conflicts where multiple relationships try and use the same field name. This can be avoided by careful use of naming conventions or by specifically tagging the conflicting relations with their preferred name.
Customising
This preset is just one file, simply copy it into your project and customise it as you see fit.
Alternatively, you can write your own inflection plugin.
Changes:
Given these tables:
create table companies (
id serial primary key,
name text not null
);
create table beverages (
id serial primary key,
company_id int not null references companies,
distributor_id int references companies,
name text not null
);Query.allCompanies👉Query.companies(disable viapgSimplifyAllRows = false)Query.allBeverages👉Query.beveragesBeverage.companyByCompanyId👉Beverage.companyBeverage.companyByDistributorId👉Beverage.distributorCompany.beveragesByCompanyId👉Company.beverages(because thecompany_idcolumn follows the[table_name]_idnaming convention)- All update mutations now accept
patchinstead ofcompanyPatch/beveragePatch(disable viapgSimplifyPatch = false) - If you prefer lists then you can use
pgOmitListSuffix = trueto omit theListsuffix, and instead appendConnectionto connections - Fields where the singular and plural are the same and a distinct plural is
required are force-pluralised ("fishes") to avoid conflicts (e.g.
singularize("fish") === pluralize("fish")).
Note: Company.beveragesByDistributorId will remain, because distributor_id
does not follow the [table_name]_id naming convention, but you could rename
this yourself with a smart comment:
comment on constraint "beverages_distributor_id_fkey" on "beverages" is
E'@foreignFieldName distributedBeverages';or with a custom inflector plugin:
const plugin = {
name: "MyCustomInflectionPlugin",
version: "0.0.0",
inflection: {
replace: {
getOppositeBaseName(previous, options, baseName) {
return (
{
// These are the default opposites
parent: "child",
child: "parent",
author: "authored",
editor: "edited",
reviewer: "reviewed",
// 👇 Add/customise this line:
distributor: "distributed",
}[baseName] || previous.call(this, baseName)
);
},
},
},
};Installation:
yarn add @graphile/simplify-inflectionor
npm install --save @graphile/simplify-inflectionUsage:
Add the preset to your Graphile Config file, under presets:
// graphile.config.mjs or similar
import { PgSimplifyInflectionPreset } from "@graphile/simplify-inflection";
export default {
extends: [
// ... (PostGraphileAmber, etc)
PgSimplifyInflectionPreset,
],
schema: {
// ...
/*
* Uncomment if you want simple collections to lose the 'List' suffix
* (and connections to gain a 'Connection' suffix).
*/
//pgOmitListSuffix: true,
/*
* Uncomment if you want 'userPatch' instead of 'patch' in update
* mutations.
*/
//pgSimplifyPatch: false,
/*
* Uncomment if you want 'allUsers' instead of 'users' at root level.
*/
//pgSimplifyAllRows: false,
/*
* Uncomment if you want primary key queries and mutations to have
* `ById` (or similar) suffix; and the `nodeId` queries/mutations
* to lose their `ByNodeId` suffix.
*/
// pgShortPk: true,
},
};Naming your foreign key fields
By naming your foreign key along the lines of author_id or author_fk, e.g.:
CREATE TABLE posts (
id serial primary key,
author_id int not null references users,
...
);We can automatically extract the field prefix: author and call the relation
author rather than the default: user. This allows for a post to have an
author, editor, reviewer, etc. all which point to users.
The reverse, however, is not so easy. On the User type, we can't call the
reverse of all these different relations posts. The default inflector refers
to these as postsByAuthorId, postsByEditorId, etc. However we'd rather use
shorter names, so we introduce a new inflector: getOppositeBaseName. This
inflector is passed a baseName (the part without the _id/_fk suffix, e.g.
author, editor, reviewer above) and should return the opposite of that
base name which will be prepended to the target type to produce, e.g.
authoredPosts, editedPosts, reviewedPosts. Failing this, we just fall back
to the default (verbose) inflector; it will be up to you to add smart comments
or a custom inflector to override these.
Handling field conflicts:
In most cases, the conflict errors will guide you on how to fix these issues using smart comments.
Smart Tags
@listSuffix
@listSuffix allows you to override the default naming on a per-entity basis,
overriding pgOmitListSuffix. For example, with pgOmitListSuffix: true, you
can apply @listSuffix include to have the -List suffix appended to the
simple collection generated for that table, and remove the -Connection suffix
from the Relay connection. When pgOmitListSuffix is not true, you can use
@listSuffix omit to selectively omit the -List suffix on simple collections
and append -Connection to the Relay connection instead.
If @listSuffix is set, the only valid values are "omit" and "include". Any
other value will cause an error.
| @listSuffix omit | @listSuffix include | |
|---|---|---|
| Relay Connection | companiesConnection | companies |
| Simple Collection | companies | companiesList |
NOTE:
@listSuffixwill have no effect when using@foreignSimpleFieldName.
Applies to:
- tables
- foreign key constraints
- computed column functions returning
SETOF <record type>
9 months ago
5 months ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago