38
loading...
This website collects cookies to deliver better user experience
create-next-app
CLI. This is a command line tool that enables us to quickly start building a new Next.js application. We can use it to create a new skeleton Next.js project or select from many of the example Next.js projects.npx create-next-app next
next
directory, and run yarn dev
to start a local web server serving our Next.js application. We should see something like this with some placeholder content:pages/api
that will be mapped to a new API endpoint.create-next-app
includes an API route example in pages/api/hello.js
:// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
localhost:3000/api/hello
we'll get back a simple JSON object:{
name: "John Doe"
}
micro
package and apollo-server-micro
to set up a simple GraphQL server as an API route.yarn add apollo-server-micro micro graphql
import { gql, ApolloServer } from "apollo-server-micro";
const typeDefs = gql`
type User {
id: ID
}
type Query {
getUser: User
}
`;
const resolvers = {
Query: {
getUser: () => {
return {
id: "Foo",
};
},
},
};
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
});
const startServer = apolloServer.start();
export default async function handler(req, res) {
await startServer;
await apolloServer.createHandler({
path: "/api/graphql",
})(req, res);
}
export const config = {
api: {
bodyParser: false,
},
};
getUser
and a single User
type that has only one field, id
and a resolver function that returns a single hardcoded User
object.import { ApolloServerPluginLandingPageGraphQLPlayground } from "apollo-server-core";
...
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
playground: true,
plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
});
localhost:3000/graphql/api
in a web browser we should see the familiar GraphQL Playground tool. To verify that our GraphQL server is working properly we can run this query:{
getUser {
id
}
}
getUser
resolver function:{
data: {
getUser: {
id: "Foo"
}
}
}
yarn add @neo4j/graphql neo4j-driver
@relationship
directive is used in the GraphQL type definitions to encode the relationship type and direction in the property graph modeltype User {
username: String
created: DateTime
karma: Int
about: String
avatar: String
articles: [Article] @relationship(type: "SUBMITTED", direction: OUT)
invited: [User] @relationship(type: "INVITED_BY", direction: IN)
invited_by: [User] @relationship(type: "INVITED_BY", direction: OUT)
}
type Article {
id: ID
url: String
score: Int
title: String
comments: String
created: DateTime
user: User @relationship(type: "SUBMITTED", direction: IN)
tags: [Tag] @relationship(type: "HAS_TAG", direction: OUT)
}
type Tag {
name: String
articles: [Article] @relationship(type: "HAS_TAG", direction: IN)
}
Neo4jGraphQL
class constructor to generate our GraphQL API.@exclude
directive in our GraphQL type definitions to prevent any mutations from being added to the schema - we want this to be a read-only API, at least for now.import { gql, ApolloServer } from "apollo-server-micro";
import { ApolloServerPluginLandingPageGraphQLPlayground } from "apollo-server-core";
import {Neo4jGraphQL} from "@neo4j/graphql"
import neo4j from "neo4j-driver"
import 'ts-tiny-invariant' // importing this module as a workaround for issue described here: https://github.com/vercel/vercel/discussions/5846
const typeDefs = gql`
type User @exclude(operations: [CREATE, UPDATE, DELETE]) {
username: String
created: DateTime
karma: Int
about: String
avatar: String
articles: [Article] @relationship(type: "SUBMITTED", direction: OUT)
invited: [User] @relationship(type: "INVITED_BY", direction: IN)
invited_by: [User] @relationship(type: "INVITED_BY", direction: OUT)
}
type Article @exclude(operations: [CREATE, UPDATE, DELETE]) {
id: ID
url: String
score: Int
title: String
comments: String
created: DateTime
user: User @relationship(type: "SUBMITTED", direction: IN)
tags: [Tag] @relationship(type: "HAS_TAG", direction: OUT)
}
type Tag @exclude(operations: [CREATE, UPDATE, DELETE]) {
name: String
articles: [Article] @relationship(type: "HAS_TAG", direction: IN)
}
`;
const driver = neo4j.driver(
process.env.NEO4J_URI,
neo4j.auth.basic(process.env.NEO4J_USER, process.env.NEO4J_PASSWORD)
)
const neoSchema = new Neo4jGraphQL({typeDefs, driver})
const apolloServer = new ApolloServer({
schema: neoSchema.schema,
playground: true,
introspection: true,
plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
});
const startServer = apolloServer.start();
export default async function handler(req, res) {
await startServer;
await apolloServer.createHandler({
path: "/api/graphql",
})(req, res);
}
export const config = {
api: {
bodyParser: false,
},
};
.env
files, so let's create a .env.local
file where we'll add the credentials for our Neo4j Aura instance. We'll also set the DEBUG
environment variable to enable debug logging for the Neo4j GraphQL library. This will log the generated Cypher queries among other things, which can be helpful to understand how the database queries are generated from GraphQL operations.NEO4J_USER=neo4j
NEO4J_URI=neo4j+s://YOUR NEO4J AURA URI HERE
NEO4J_PASSWORD=YOUR NEO4J AURA PASSWORD HERE
DEBUG=@neo4j/graphql:*
localhost:3000/api/graphql
that we can use to fetch data from our Neo4j Aura database using GraphQL. Next, we'll deploy our Next.js application on Vercel so that it will be publicly accessible.next
directory. We'll also add our Neo4j Aura connection credentials as environment variables, setting values for NEO4J_PASSWORD
, NEO4J_URI
, and NEO4J_USER
in the Vercel project configuration.https://lobste-rs-graph.vercel.app/api/graphql
and test our GraphQL endpoint: