crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Type safety with custom resolvers and `selectGraphQLResultFromTable`

Open rohanliston opened this issue 3 years ago • 5 comments
trafficstars

Summary

Is it possible to have type-safe queries in makeExtendSchemaPlugin resolvers, so that the resolvers break at build time if incompatible database schema changes are made?

Details

I've been following the makeExtendSchemaPlugin docs and have written some custom resolvers.

I've converted my resolvers to TypeScript and have used Zapatos to generate a TypeScript schema from the DB. Now I get squiggly lines in my IDE and compile errors if my queries don't match the database schema (see images below)

This is perfect, but I don't see a way to get the same type-safety when using the selectGraphQLResultFromTable query builder. This means the resolvers may still compile if I change the schema, but fail at runtime.

I've tried building the queries using Zapatos and using a hacked version of the resulting SQL in the query builder using sql.raw(), but this seems like a bad idea.

Is there some way to get type safety when using selectGraphQLResultFromTable? If not, could I start a feature-request discussion to have Postgraphile generate a TypeScript schema to be used with pgClient and selectGraphQLResultFromTable?

Additional context

Squigglies in VS Code

image

TypeScript compile errors

image

rohanliston avatar Aug 03 '22 10:08 rohanliston

selectGraphQLResultFromTable is going away in PostGraphile V5; it was only ever intended to be a wrapper method to stop people having to write so much boilerplate. I'd love your input on the new stuff once it's ready to be shared publicly, so I'll leave this open.

benjie avatar Aug 03 '22 12:08 benjie

Thanks @benjie, happy to provide input once it's ready. I'm loving Postgraphile so far!

In a nutshell, I think it would be great if we could:

  • Write custom resolvers in TypeScript without having to manually compile them (i.e. pass .ts files directly to --append-plugins)
  • Have a single, consistent way to talk to the DB in resolvers (instead of pgClient and selectGraphQLResultFromTable)
  • Get build-time errors if our queries no longer match the database schema.

Feel free to reach out if I can help further.

rohanliston avatar Aug 04 '22 01:08 rohanliston

Bullet 1: use ts-node and that should work. It’s a Node concern, not a PostGraphile concern.

Bullet 2: pgClient is for side effects and data for your own usage, selectGraphQLResultsFromTable is for returning data to GraphQL. Their intended usage does not overlap, for example you should never look inside the data returned by selectGraphQLResultsFromTable.

Bullet 3: yep, that’d be nice.

benjie avatar Aug 04 '22 07:08 benjie

Bullet 1: use ts-node and that should work. It’s a Node concern, not a PostGraphile concern.

:+1: Makes sense. I'm currently just using tsc for this but will give ts-node a look, thanks.

Bullet 2: pgClient is for side effects and data for your own usage, selectGraphQLResultsFromTable is for returning data to GraphQL. Their intended usage does not overlap, for example you should never look inside the data returned by selectGraphQLResultsFromTable.

Sorry, I wasn't very clear in what I was trying to say. What I'm suggesting is having a common SQL template string that can be used as input for both purposes, even though the output is different.

Compiling the template for use with pgClient would produce an SQL statement that the database understands. Compiling for a GraphQL response would produce a list of SQL entries like it does now.

(This may be a totally naive suggestion since I've only just started using Postgraphile :sweat_smile:)

Bullet 3: yep, that’d be nice.

Would recommend a look at Zapatos of you haven't already, even if just for inspiration. I found it very easy to use.

rohanliston avatar Aug 05 '22 02:08 rohanliston

pg-sql2, the library we use for templating SQL, can also be used with pgClient - please refer to its readme 👍

I’ve used Zapatos within PostGraphile projects 👍

benjie avatar Aug 05 '22 08:08 benjie

Closing this as we won't be changing it in V4 and V5 doesn't use this system.

benjie avatar Sep 29 '23 14:09 benjie