A GraphQL to SQL query execution layer for query planning and batch data fetching.
MIT License
Bot releases are hidden (Show)
Breaking changes:
It is no longer guaranteed that a field's value is available under source[fieldName]
in a custom resolver. Instead, custom resolvers on non-trivial fields need to use GraphQL's default resolver to get the field value:
import { defaultFieldResolver } from 'graphql'
const User = new GraphQLObjectType({
//...
fields: () => ({
//...
following: {
// ...
resolve: (source, args, context, info) => {
const value = defaultFieldResolver(source, args, context, info)
return processUsers(value)
}
}
})
})
See the docs on custom resolvers for more details.
Full Changelog: https://github.com/join-monster/join-monster/compare/v3.3.5...v4.0.0
Published by nicoabie 5 months ago
aliasPrefix
option by @jasonwoodland in https://github.com/join-monster/join-monster/pull/533
Full Changelog: https://github.com/join-monster/join-monster/compare/v3.3.4...v3.3.5
Published by nicoabie 5 months ago
Full Changelog: https://github.com/join-monster/join-monster/compare/v3.1.1...v3.3.4
Published by acarl005 over 7 years ago
New features:
LIMIT
functionality, supported on all fieldsWHERE
and ORDER BY
clauses on the junction table or the main table, including paginated fields.where
functions that depend on args and info from the parent/ancestors.Breaking changes:
where
, orderBy
, and sortKey
on many-to-many paginated fields used to be applied to the junction table. This has changed, and will be applied to the main table instead in order to be consistent with non-paginated junctions. If the old behavior is desired, you can nest those properties inside the junction
object, which is part of the new API.where
and sqlExpr
to the field's SQL AST Node, which is a lot more useful.// this...
{
type: new GraphQLList(User),
junctionTable: 'relationships',
sqlJoins: [
(followers, relations) => `${followers}.id = ${relations}.follower_id`,
(relations, followees) => `${relations}.followee_id = ${followees}.id`
]
}
// is now this...
{
type: new GraphQLList(User),
junction: {
sqlTable: 'relationships',
sqlJoins: [
(followers, relations) => `${followers}.id = ${relations}.follower_id`,
(relations, followees) => `${relations}.followee_id = ${followees}.id`
]
}
}
// this...
{
type: new GraphQLList(User),
junctionTable: 'relationships',
junctionTableKey: [ 'follower_id', 'followee_id' ],
junctionBatch: {
thisKey: 'follower_id',
parentKey: 'id',
sqlJoin: (relations, followees) => `${relations}.followee_id = ${followees}.id`
}
}
// is now this...
{
type: new GraphQLList(User),
junction: {
sqlTable: 'relationships',
uniqueKey: [ 'follower_id', 'followee_id' ],
sqlBatch: {
thisKey: 'follower_id',
parentKey: 'id',
sqlJoin: (relations, followees) => `${relations}.followee_id = ${followees}.id`
}
}
}
// this...
{
type: UserConnection,
args: forwardConnectionArgs,
sqlPaginate: true,
orderBy: {
created_at: 'DESC',
followee_id: 'ASC'
},
junctionTable: 'relationships',
sqlJoins: [
(followers, relations) => `${followers}.id = ${relations}.follower_id`,
(relations, followees) => `${relations}.followee_id = ${followees}.id`
]
}
// is now this...
{
type: UserConnection,
args: forwardConnectionArgs,
sqlPaginate: true,
junction: {
sqlTable: 'relationships',
sqlJoins: [
(followers, relations) => `${followers}.id = ${relations}.follower_id`,
(relations, followees) => `${relations}.followee_id = ${followees}.id`
],
// the order now goes inside the `junction` if you want to sort on the junction table
orderBy: {
created_at: 'DESC',
followee_id: 'ASC'
}
}
// or you could apply the order on the user table by putting it out here
//orderBy: {
// created_at: 'DESC',
// id: 'ASC'
//}
// you could also place a `where` at either
}
Published by acarl005 over 7 years ago
Published by acarl005 over 7 years ago
More advanced query planning has arrived! One of the greatest criticisms of Join Monster has been the heavy use of JOIN
s, which can be an expensive database operation. One of the benefits of DataLoader was the ability to simply batch queries. In this release, Join Monster can do both!
You can plan queries that get all your data in a single request using joins, or you can get them in separate batches with queries that use WHERE IN
to get the right data. You can mix these approaches together to find the optimal query plans for your application.
getSQL
method removed. No longer makes sense in he new multiple-query paradigm.total
to the connection object instead of the pageInfo
.'standard'
dialect is deprecated because nothing really implements the standard. The new default is 'sqlite3'
.joinTable
is deprecated. It was renamed to junctionTable
to avoid over-use of the word "join".Published by acarl005 over 7 years ago
The v0 major version will be stable after this point.
The pre-release of v1.0.0 is coming soon. The most important new feature will be the option to use DataLoader-style batching instead of joins. Join Monster will have more advanced query planning in order to balance the optimizations on network latency due to roundtrips and duplicated data due to joins. Schemas can mix joins and batches to tune the query plans to the heuristics of their application. There will be a few breaking changes.
Q: Is support for Apollo server planned for the near future?
A: We do not use Apollo, so it is not a priority. However, we do want Join Monster to support it, as it is the most highly requested feature. How long this takes will depend largely on community engagement.