forked from join-monster/join-monster
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the ability for scalars to be powered by sqlTables
join-monster excels at retrieving exactly the fields asked for by a given GraphQL query, but sometimes, there isn't an exact 1-1 correspondence between the desired fields in a GraphQL API and the table structure powering the system. Sometimes, data is normalized in the database or broken out into many tables for performance or reporting reasons or whatever, and join-monster supports these non 1-1 mappings fine with sqlExpr, alwaysFetch, and custom resolvers just fine, except when the "virtual" field is a scalar. I've ended up having to use a few custom scalars in my application, mostly from the `graphql-scalars` package as well as a couple other random ones, and I have one that is powered by a whole other table in the actual database schema. As an example, I have a `Post` object with normal fields that map to columns, but then a `tags` field on the Post that should return a string of tags, where the Tag is a custom scalar to apply some special parsing and formatting to the tag. The tags are stored in their own tags table in the database. To expose this using `join-monster`, I could create a whole new `GraphQLObjectType` to represent Tags and then have a `{name, id}` field or whatever, but I feel like that is changing the design of the API to accomodate join-monster (and GraphQL to an extent), instead of making the nicest API for developers, which would just be a plain old array of strings. So, I'd like to be able to do a `GraphQLList` of `Tag`, where `Tag` is a `new GraphQLScalar`, and have `join-monster` traverse that join and fetch my tags from the database. Turns out the only thing preventing this was the whitelist of types that `join-monster` looks for `sqlTable` on, so that's the only actual functional change in this PR. This is probably a pretty rare thing, but it's super handy for these custom scalars, as well as the JSON scalar escape hatch that folks might use to escape the strict typing shackles of GraphQL when they need to.
- Loading branch information
Showing
17 changed files
with
329 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { GraphQLInt, GraphQLScalarType, Kind } from 'graphql' | ||
import { q } from '../shared' | ||
import { connectionDefinitions } from 'graphql-relay' | ||
const { PAGINATE, DB } = process.env | ||
|
||
// This is to test Scalars being extended with join-monster properties and is not a great way to actually model tags | ||
export const Tag = new GraphQLScalarType({ | ||
name: 'Tag', | ||
description: 'Custom scalar representing a tag', | ||
extensions: { | ||
joinMonster: { | ||
sqlTable: `(SELECT * FROM ${q('tags', DB)})`, | ||
uniqueKey: 'id', | ||
alwaysFetch: ['id', 'tag', 'tag_order'] | ||
} | ||
}, | ||
parseValue: String, | ||
serialize: String, | ||
parseLiteral(ast) { | ||
if (ast.kind === Kind.STRING) { | ||
return ast.value | ||
} | ||
return null | ||
} | ||
}) | ||
|
||
const connectionConfig = { nodeType: Tag } | ||
if (PAGINATE === 'offset') { | ||
connectionConfig.connectionFields = { | ||
total: { type: GraphQLInt } | ||
} | ||
} | ||
const { connectionType: TagConnection } = connectionDefinitions( | ||
connectionConfig | ||
) | ||
export { TagConnection } |
Oops, something went wrong.