Inflection
Inflection governs how things are named whilst building your PostGraphile schema. "Inflection" is the system of naming things; it's composed of a large set of named functions, and we call each of these inflection functions an "inflector."
The inflectors that you have available will depend on the plugins and presets
you're using. To get a list of the inflectors available to you, you can use
TypeScript autocompletion, or if you're a sponsor you can install the
graphile
package and run yarn graphile inflection list
(or equivalent for
other package managers).
In GraphQL, types typically use singular UpperCamelCase
(PascalCase
);
fields, arguments and directives typically use camelCase
; and enum values
typically use CONSTANT_CASE
. These conventions can be seen in the GraphQL
specification itself. The
default inflectors attempt to map things to natural names in GraphQL whilst
avoiding naming conflicts. For example:
- Table names are singularized and changed to UpperCamelCase:
pending_users
→PendingUser
- Column names are changed to camelCase:
created_at
→createdAt
- Relations reference the target type and the referencing columns:
postsByAuthorId
(see "advice" below about making this shorter!)
But if you don't want this (or it's doing something wrong), then you can fix it by overriding inflectors!
Overriding Naming - One-off
If you want to rename just one field or type, your best bet is to use a smart tag; e.g. for a table you might do:
COMMENT ON TABLE post IS E'@name message';
Each inflector is responsible for checking for any relevant smart tags and honouring them.
Overriding Inflection
You can easily write a plugin to override an individual inflector, it just
needs to add the new inflector under the inflection.replace
object; an
example might look like:
export default {
name: "ReplacePatchTypeInflectorPlugin",
version: "0.0.0",
inflection: {
replace: {
patchType(previous, resolvedPreset, typeName) {
return this.upperCamelCase(`${typeName}-change-set`);
},
},
},
};
In this example, previous
is the previous inflector (in case you only want to
override in certain circumstances) - you would call it using the same
arguments, just dropping the first two - so in this case: previous(typeName)
.
TypeScript is your friend when replacing inflectors, it should know what inflectors are available, their documentation, and the types of all their arguments.
Advice
By default, the relation field names are explicit to avoid accidental
conflicts, and can make your schema somewhat verbose, e.g. userByAuthorId
,
userByEditorId
, userByPublisherId
, etc.
Some people like this verbosity; however if you, like us, prefer shorter names
then we encourage you use
the @graphile/simplify-inflection
plugin.
This would automatically change those fields to be named author
, editor
and
publisher
respectively.
import { PgSimplifyInflectionPreset } from "@graphile/simplify-inflection";
const preset = {
extends: [
PgSimplifyInflectionPreset,
//...
],
//...
};
Our maintainer, Benjie, prefers to use this plugin in all his projects.
Listing available inflectors
We've built a command into our sponsors-only graphile
development assistant
to help you determine all the inflectors available to you:
- npm
- Yarn
- pnpm
npm install --save-dev graphile@beta
npx graphile inflection list
yarn add --dev graphile@beta
npx graphile inflection list
pnpm add --save-dev graphile@beta
npx graphile inflection list