This repository has been archived by the owner on Oct 28, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
86 additions
and
127 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,24 @@ | ||
/* | ||
* Import the 'Post' type from the '@prisma/client' package. | ||
* This type represents a post in your application. | ||
*/ | ||
import type { Post } from "@prisma/client"; | ||
|
||
/* | ||
* Import the 'Context' type. | ||
* This type represents the context of a GraphQL resolver function, which includes any data that every resolver | ||
* function should have access to, like the current user or database access. | ||
*/ | ||
import type { Context } from "@/utils"; | ||
|
||
/* | ||
* Import the 'Mutation' and 'Query' objects. | ||
* These objects include resolver functions for the mutations and queries defined in your GraphQL schema. | ||
*/ | ||
import type { Post } from "@prisma/client"; | ||
import Mutation from "./mutation"; | ||
import Query from "./query"; | ||
|
||
/* | ||
* Export an object that includes the 'Query' and 'Mutation' objects and a 'Post' object. | ||
* The 'Post' object includes an 'author' method, which is a resolver function for getting the author of a post. | ||
*/ | ||
export default { | ||
Query, | ||
Mutation, | ||
Post: { | ||
author: (parent: Post, _args: unknown, { prisma }: Context) => { | ||
/* | ||
* The 'author' method takes three arguments: 'parent', '_args', and 'ctx'. | ||
* 'parent' is the post for which to get the author. | ||
* '_args' includes any arguments passed to the 'author' query, but it's not used in this function, so it's named '_args'. | ||
* 'ctx' is the context of the resolver function, which includes the 'prisma' client. | ||
* | ||
* The function returns a promise that resolves to the author of the post. | ||
* It uses the 'prisma' client to find the post in the database and get its author. | ||
*/ | ||
return prisma.post | ||
.findUnique({ | ||
where: { id: parent.id }, | ||
}) | ||
.author(); | ||
}, | ||
}, | ||
Subscription: { | ||
postCreated: { | ||
// More on pubsub below | ||
//subscribe: () => pubsub.asyncIterator(["POST_CREATED"]), | ||
}, | ||
}, | ||
}; |
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 |
---|---|---|
@@ -1,34 +1,87 @@ | ||
import prisma from "@/config/database"; | ||
import { getResolvers, getSchema, getUserId, type Context } from "@/utils"; | ||
import { ApolloServer } from "@apollo/server"; | ||
import { startStandaloneServer } from "@apollo/server/standalone"; | ||
import prisma from "./config/database"; | ||
import { getResolvers, getSchema, getUserId, type Context } from "./utils"; | ||
import { expressMiddleware } from "@apollo/server/express4"; | ||
import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer"; | ||
import { makeExecutableSchema } from "@graphql-tools/schema"; | ||
import cors from "cors"; | ||
import express from "express"; | ||
import { useServer } from "graphql-ws/lib/use/ws"; | ||
import http from "http"; | ||
import { WebSocketServer } from "ws"; | ||
|
||
const resolvers = await getResolvers(); | ||
const typeDefs = await getSchema(); | ||
|
||
// Required logic for integrating with Express | ||
const app = express(); | ||
// Our httpServer handles incoming requests to our Express app. | ||
// Below, we tell Apollo Server to "drain" this httpServer, | ||
// enabling our servers to shut down gracefully. | ||
const httpServer = http.createServer(app); | ||
|
||
// Creating the WebSocket server | ||
const wsServer = new WebSocketServer({ | ||
// This is the `httpServer` we created in a previous step. | ||
server: httpServer, | ||
// Pass a different path here if app.use | ||
// serves expressMiddleware at a different path | ||
path: "/subscriptions", | ||
}); | ||
|
||
const schema = makeExecutableSchema({ typeDefs, resolvers }); | ||
|
||
// Hand in the schema we just created and have the | ||
// WebSocketServer start listening. | ||
const serverCleanup = useServer({ schema }, wsServer); | ||
|
||
const server = new ApolloServer<Context>({ | ||
typeDefs: await getSchema(), | ||
resolvers, | ||
schema, | ||
// only enable introspection for development | ||
introspection: process.env.NODE_ENV === "development", | ||
status400ForVariableCoercionErrors: true, | ||
// you can enable the following option during development to get more detailed error messages | ||
includeStacktraceInErrorResponses: false, | ||
plugins: [ | ||
// Proper shutdown for the HTTP server. | ||
ApolloServerPluginDrainHttpServer({ httpServer }), | ||
|
||
// Proper shutdown for the WebSocket server. | ||
{ | ||
async serverWillStart() { | ||
return { | ||
async drainServer() { | ||
await serverCleanup.dispose(); | ||
}, | ||
}; | ||
}, | ||
}, | ||
], | ||
}); | ||
|
||
// Passing an ApolloServer instance to the `startStandaloneServer` function: | ||
// 1. creates an Express app | ||
// 2. installs your ApolloServer instance as middleware | ||
// 3. prepares your app to handle incoming requests | ||
const { url } = await startStandaloneServer(server, { | ||
listen: { port: process.env.PORT || 4000 }, | ||
context: async ({ req, res }) => { | ||
return { | ||
// Ensure we wait for our server to start | ||
await server.start(); | ||
|
||
// Set up our Express middleware to handle CORS, body parsing, | ||
// and our expressMiddleware function. | ||
app.use( | ||
"/", | ||
cors<cors.CorsRequest>(), | ||
express.json(), | ||
// expressMiddleware accepts the same arguments: | ||
// an Apollo Server instance and optional configuration options | ||
expressMiddleware(server, { | ||
context: async ({ req, res }) => ({ | ||
req, | ||
res, | ||
userId: getUserId(req), | ||
prisma, | ||
}; | ||
}, | ||
}); | ||
}), | ||
}), | ||
); | ||
|
||
console.log(`🚀 Server ready at: ${url}`); | ||
// Modified server startup | ||
await new Promise<void>((resolve) => | ||
httpServer.listen({ port: process.env.PORT || 4000 }, resolve), | ||
); | ||
console.log("🚀 Server ready at http://localhost:4000/"); |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.