Skip to content

Instantly share code, notes, and snippets.

@kissmygritts
Created September 22, 2018 21:02
Show Gist options
  • Save kissmygritts/f0e957f94f5b557d7e137206d9e60316 to your computer and use it in GitHub Desktop.
Save kissmygritts/f0e957f94f5b557d7e137206d9e60316 to your computer and use it in GitHub Desktop.
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