Postgraphile: Is there a way to store JSON without having to escape it to a string?

Created on 30 Jan 2019  ·  7Comments  ·  Source: graphile/postgraphile

I'm submitting a

  • [ ] bug report
  • [ ] feature request
  • [ x] question

PostGraphile version:
4.3.1

Hey so i looked through the issues on here but couldn't find an example / how to do this.

Basically I've using JSON string template literals to format the graphql requests before hitting the server.

However in order to store JSON I currently have to fully escape it like so

"{\"bitm\":45,\"bplg\":55}"

This means however I can't then use the usual Postgres tools of ->> to query it.

Is there something I am missing? Or is this not possible?

Thanks!

❔ question

Most helpful comment

I strongly advise you use static queries rather than query interpolation. To do so, you'd submit something like the following:

const requestBody = {
  query: `
  mutation CreateEstimate($uuid: UUID!, $guess: JSON!) {
    createEstimate(
      input: { 
        estimate:
          { uuid: $uuid,  guess: $guess }
        }
      ) {
      estimate {
        uuid
      }
    }
  }`,
  variables: {
    uuid: "1234",
    guess: {cong: 82, bplg: 12}
  }
};

And submit that to the server with Content-Type: application/json

All 7 comments

If you use the --dynamic-json option then you don’t need to escape JSON - just pass it through as normal JSON. You can store it into JSON columns and use the standard JSON operators in PostgreSQL with it.

[semi-automated message] Thanks for your question; hopefully we're well on the way to helping you solve your issue. This doesn't currently seem to be a bug in the library so I'm going to close the issue, but please feel free to keep requesting help below and if it does turn out to be a bug we can definitely re-open it 👍

Hey @benjie thanks for the quick reply.

So I'm not too sure just how I would pass it normal JSON.

Say I have a function like so

const addEstimate = (uuid, guess) => ({
  query: `
     mutation {
      createEstimate(
        input: { 
          estimate:
            { uuid: "${uuid}", guess: "${guess}" }
          }
        ) {
        estimate {
          uuid
        }
      }
    }
  `,
});

Where guess is the jsonb.

If I pass it just the usual JSON object JS will convert it to guess: "[object Object]" as expected when trying to print an object.

So you'd have to use JSON.stringify. However will then play havoc with the string due to both using double qoutes to be valid.

   mutation {
    createEstimate(
      input: { 
        estimate:
          { uuid: "1234",  guess: "{"cong":82,"bplg":12}" }
        }
      ) {
      estimate {
        uuid
      }
    }
  } 

But then escaping the json like so {\"cong\":82,\"bplg\":12} causes the original issue. So how do I do it? Thanks!

Ah hang on I think I've just spotted my mistake

So For future users, you need to pass in the JSON stringified but without the qoutes.

for instance this was suffiecent for me

JSON.stringify(guess).replace(/"/g,"")

     mutation {
      createEstimate(
        input: { 
          estimate:
            { uuid: "fb456cd",  guess: {conm:9} }
          }
        ) {
        estimate {
          uuid
        }
      }
    }

I strongly advise you use static queries rather than query interpolation. To do so, you'd submit something like the following:

const requestBody = {
  query: `
  mutation CreateEstimate($uuid: UUID!, $guess: JSON!) {
    createEstimate(
      input: { 
        estimate:
          { uuid: $uuid,  guess: $guess }
        }
      ) {
      estimate {
        uuid
      }
    }
  }`,
  variables: {
    uuid: "1234",
    guess: {cong: 82, bplg: 12}
  }
};

And submit that to the server with Content-Type: application/json

Ah I was thinking about this early that my version would be very easy to maliciously inject.

Thank you for the example!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CarlFMateus picture CarlFMateus  ·  4Comments

outsidenote picture outsidenote  ·  4Comments

jwdotjs picture jwdotjs  ·  5Comments

marshall007 picture marshall007  ·  3Comments

ssomnoremac picture ssomnoremac  ·  5Comments