Giter Club home page Giter Club logo

pg-simplify-inflector's Introduction

@graphile-contrib/pg-simplify-inflector

This plugin 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 plugin to your schema is almost certainly a breaking change, so do it before you ship anything! This is the primary reason this isn't enabled by default in PostGraphile.

This plugin is recommended for all PostGraphile users.

Customising

This plugin is implemented as a single JS file that does not need to be compiled at all - you can 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 via pgSimplifyAllRows = false)
  • Query.allBeverages ๐Ÿ‘‰ Query.beverages
  • Beverage.companyByCompanyId ๐Ÿ‘‰ Beverage.company
  • Beverage.companyByDistributorId ๐Ÿ‘‰ Beverage.distributor
  • Company.beveragesByCompanyId ๐Ÿ‘‰ Company.beverages (because the company_id column follows the [table_name]_id naming convention)
  • All update mutations now accept patch instead of companyPatch / beveragePatch (disable via pgSimplifyPatch = false)
  • If you are using pgSimpleCollections = "only" then you can set pgOmitListSuffix = true to omit the List suffix
  • 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:

module.exports = makeAddInflectorsPlugin(
  {
    getOppositeBaseName(baseName) {
      return (
        {
          // These are the default opposites
          parent: "child",
          child: "parent",
          author: "authored",
          editor: "edited",
          reviewer: "reviewed",

          // ๐Ÿ‘‡ Add/customise this line:
          distributor: "distributed",
        }[baseName] || null
      );
    },
  },
  true
);

Installation:

yarn add @graphile-contrib/pg-simplify-inflector

or

npm install --save @graphile-contrib/pg-simplify-inflector

Usage:

CLI:

postgraphile --append-plugins @graphile-contrib/pg-simplify-inflector

Library:

const PgSimplifyInflectorPlugin = require("@graphile-contrib/pg-simplify-inflector");

// ...

app.use(
  postgraphile(process.env.AUTH_DATABASE_URL, "app_public", {
    appendPlugins: [PgSimplifyInflectorPlugin],

    // Optional customisation
    graphileBuildOptions: {
      /*
       * 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,
    },
    // ... other settings ...
  })
);

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.