First server
Serve a Pothos schema over HTTP with graphql-yoga and run a query against it.
With a schema built, the next step is to put it behind an HTTP endpoint. These guides use graphql-yoga, but the GraphQLSchema returned by toSchema() should be compatible with any other GraphQL server implementation.
Install yoga
npm install graphql-yogaThe schema
Here's a small schema with a single hello field:
import SchemaBuilder from '@pothos/core';
const builder = new SchemaBuilder({});
builder.queryType({
fields: (t) => ({
hello: t.string({
args: { name: t.arg.string() },
resolve: (_root, { name }) => `Hello, ${name ?? 'friend'}.`,
}),
}),
});
export const schema = builder.toSchema();Save it as schema.ts; it exports schema, which is all the server imports. The hello field takes an optional name argument declared with t.arg.string() (the Arguments guide covers arguments).
The server
createYoga takes the schema and returns a request handler you can pass straight to Node's built-in HTTP server:
import { createServer } from 'node:http';
import { createYoga } from 'graphql-yoga';
import { schema } from './schema';
const yoga = createYoga({
schema,
context: () => ({}),
});
const server = createServer(yoga);
server.listen(4000, () => {
console.log('Ready at http://localhost:4000/graphql');
});Run it with npx tsx server.ts (or compile with tsc and run the output). yoga serves the API at /graphql, and by default it also serves the GraphiQL explorer at that same URL — open http://localhost:4000/graphql in a browser to load it. The port is whatever you pass to server.listen.
Running a query
In GraphiQL, run:
query Greet {
hello(name: "Frodo")
}yoga responds with:
{
"data": {
"hello": "Hello, Frodo."
}
}The context factory
The context option is a function that runs while yoga handles a request; whatever it returns becomes the ctx value every resolver can read. The server above returns {}, so ctx is empty. In a real app the factory reads the incoming request and returns what resolvers need, such as the signed-in user and a database client:
import { initContextCache } from '@pothos/core';
const yoga = createYoga({
schema,
context: async ({ request }) => ({
...initContextCache(),
user: await getUser(request.headers.get('authorization')),
db,
}),
});Spreading initContextCache() into the returned object sets up the per-request cache some plugins rely on; including it in every context factory keeps those plugins working. Declaring a matching Context type on the builder makes ctx fully typed in every resolver. The Context guide covers what belongs on context and how to wire the types.