Created
September 22, 2018 21:02
-
-
Save kissmygritts/f0e957f94f5b557d7e137206d9e60316 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import { makeExecutableSchema } from 'graphql-tools'; | |
// data | |
const posts = [ | |
{ id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 }, | |
{ id: 2, authorId: 2, title: 'Welcome to Apollo', votes: 3 }, | |
{ id: 3, authorId: 2, title: 'Advanced GraphQL', votes: 1 }, | |
{ id: 4, authorId: 3, title: 'Launchpad is Cool', votes: 7 }, | |
{ id: 5, authorId: 3, title: 'Apollo-Client, the Artemis to My Apollo Server', votes: 7 }, | |
{ id: 6, authorId: 1, title: 'Illuminate Errors with Apollo 2.0', votes: 7 }, | |
{ id: 7, authorId: 2, title: 'Artistic Frontends with Apollo-Client', votes: 7 }, | |
{ id: 8, authorId: 2, title: 'Apollo Engine On Target Analytics', votes: 7 }, | |
{ id: 9, authorId: 3, title: 'Singing Praises to the Apollo Team', votes: 7 }, | |
{ id: 10, authorId: 3, title: 'Cure Your GraphQL API Woes With Apollo', votes: 7 }, | |
]; | |
// offset pagination | |
// simple, easy | |
const typeDefs = ` | |
interface Node { | |
id: Int! | |
} | |
type Post { | |
id: Int | |
authorId: Int | |
title: String | |
} | |
type PostConnection { | |
totalCount: Int | |
pageInfo: PageInfo | |
edges: [PostEdge] | |
} | |
type PostEdge { | |
cursor: Int | |
node: Post | |
} | |
type PageInfo { | |
lastCursor: Int | |
hasNextPage: Boolean | |
} | |
type Query { | |
posts: PostConnection | |
postsOffsetPagination (offset: Int, limit: Int): [Post] | |
postsCursorPagination (first: Int, after: Int): [Post] | |
postsRelayPagination (first: Int, after: Int): PostConnection | |
} | |
`; | |
const resolvers = { | |
Query: { | |
posts: (root, args, ctx, info) => { | |
/// just get all the posts | |
return { | |
totalCount: posts.length, | |
posts: posts | |
} | |
}, | |
postsOffsetPagination: (root, args, ctx, info) => { | |
// the idea here is that you are running a query | |
// similar to a SQL query... | |
// SELECT * FROM posts LIMIT 5 OFFSET 5 | |
// I think | |
const offset = args.offset -1 | |
const limit = args.limit | |
return posts.slice(offset, offset + limit) | |
}, | |
postsCursorPagination: (root, args, ctx, info) => { | |
// my thoughts here are that we are using the | |
// parameters first and after to run a SQL | |
// query like this... | |
// SELECT * FROM posts WHERE cursorColumn > cursor LIMIT first | |
// in english... | |
// return the first 2 posts after the cursor provided | |
// we can still run this from a simple graphql schema | |
const index = posts.map(m => m.id).indexOf(args.after) | |
console.log(index) | |
// return posts.slice(index, index + args.first) | |
return posts.slice(index, index + args.first) | |
}, | |
postsRelayPagination: (root, {first, after}, ctx, info) => { | |
// very similar to postsCursorPagination, except we are | |
// representing the data as a graph, with nodes and | |
// edges. I think the example is a little contrived | |
// as I'm only paginating over a single entity (posts) | |
// rather than getting all the posts by a single author | |
// that example will come next time... | |
const index = posts.map(m => m.id).indexOf(after) | |
const totalCount = posts.length | |
const edges = posts.slice(index, index + first).map(m => ({ | |
cursor: m.id, | |
node: { ...m } | |
})) | |
const lastCursor = edges[edges.length - 1].node.id | |
const pageInfo = { | |
lastCursor, | |
hasNextPage: posts.length + first > lastCursor + first | |
} | |
return { | |
totalCount, | |
pageInfo, | |
edges | |
} | |
} | |
} | |
}; | |
export const schema = makeExecutableSchema({ | |
typeDefs, | |
resolvers, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment