Postgraphile: Errors on optional graphql mutation variables

Created on 29 Jan 2018  ยท  5Comments  ยท  Source: graphile/postgraphile

I'm submitting a ...

  • [x] question

PostGraphQL version:
3.2.0

Minimal SQL file that can be loaded into a clean database:

CREATE TABLE users (
    id integer NOT NULL,
    firstname text,
    lastname text,
    email text,
    password text,
    meta jsonb,
    slug text,
    updated_at timestamp without time zone DEFAULT now() NOT NULL,
    created_at timestamp without time zone DEFAULT now() NOT NULL,
    CONSTRAINT users_email_check CHECK ((email ~* '^.+@.+..+$'::text))
);

CREATE FUNCTION signup(firstname text, lastname text, email text, password text) RETURNS users
    LANGUAGE plpgsql STRICT SECURITY DEFINER
    AS $$
    declare
      user users;
    begin
      insert into users (
        firstname,
        lastname,
        email,
        password
      ) values (
        firstname,
        lastname,
        email,
        crypt(password, gen_salt('bf'))
      )
        returning * into user;

      return user;
    end;
    $$;

Graphql example :

// the following fails, but making firstname and lastname required do pass
//  (so String! for $firstname and $lastname) 
mutation signupFunction(
  $email: String!,
  $password: String!,
  $firstname: String,
  $lastname: String) {
    signup(input: {
      firstname: $firstname,
      lastname: $lastname,
      email: $email,
      password: $password
    }) {
      clientMutationId
    }
  }

Steps to reproduce:
Trigger the signup function via graphql with variables firstname and lastname set as optional (defined with String without !)

Current behavior:
Fails with : Variable "$firstname" of type "String" used in position expecting type "String!

Expected behavior:
Successfull response (user created without firstname and lastname, as they're not required in the database)

Most helpful comment

When using the library you can enable this by adding pgStrictFunctions: true to graphileBuildOptions; e.g.

app.use(postgraphile(process.env.DATABASE_URL, process.env.SCHEMA_NAME, {
  dynamicJson: true,
  graphileBuildOptions: {
    pgStrictFunctions: true,
  },
}));

If you use the CLI I've added a task to add support here, feel free to subscribe to it: https://github.com/graphile/postgraphile/issues/705

All 5 comments

You have defined your signup function as โ€œstrictโ€ which means if any argument is null the entire function will skip the logic and just return null. We interpret that as all the arguments being required. Remove strict and it should work as you intend.

ok thx a lot got it
The line causing problem in the migration file if i'm not mistaking :

LANGUAGE plpgsql STRICT SECURITY DEFINER

I'll probably find out; if you have a moment to confirm me, can a postgres function be partially required ?

No - PostgreSQL treats a function as either all nullable or never nullable.

However, we can apply our own rules at the GraphQL layer. I've added pgStrictFunctions option you can use with PostGraphile - anything optional should have a default, e.g.

CREATE FUNCTION signup(email text, password text, firstname text = NULL, lastname text = NULL) RETURNS users
    LANGUAGE plpgsql SECURITY DEFINER
    AS $$
    declare
      user users;
    begin
      insert into users (
        firstname,
        lastname,
        email,
        password
      ) values (
        firstname,
        lastname,
        email,
        crypt(password, gen_salt('bf'))
      )
        returning * into user;

      return user;
    end;
    $$;

Note optional args have to come at the end.

This isn't documented yet because I've not had time.

@benjie how can I add pgStrictFunctions ?

When using the library you can enable this by adding pgStrictFunctions: true to graphileBuildOptions; e.g.

app.use(postgraphile(process.env.DATABASE_URL, process.env.SCHEMA_NAME, {
  dynamicJson: true,
  graphileBuildOptions: {
    pgStrictFunctions: true,
  },
}));

If you use the CLI I've added a task to add support here, feel free to subscribe to it: https://github.com/graphile/postgraphile/issues/705

Was this page helpful?
0 / 5 - 0 ratings

Related issues

james-ff picture james-ff  ยท  4Comments

WestleyArgentum picture WestleyArgentum  ยท  3Comments

marshall007 picture marshall007  ยท  3Comments

giacomorebonato picture giacomorebonato  ยท  3Comments

safaiyeh picture safaiyeh  ยท  3Comments