Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom GraphQL Schemas (_meta, shared middleware) #1498

Open
shrugs opened this issue Feb 10, 2025 · 5 comments
Open

Custom GraphQL Schemas (_meta, shared middleware) #1498

shrugs opened this issue Feb 10, 2025 · 5 comments

Comments

@shrugs
Copy link
Contributor

shrugs commented Feb 10, 2025

Problem / use case

In namehash/ensnode we'd like to run our subgraph-compatible GraphQL schema alongside the native ponder graphql schema. In order to do so, we have to duplicate the work in middleware.ts, since the built in GraphQL middlware doesn't allow for providing the schema directly (and even when it was previously possible to inject the custom schema into the hono context, that resulted in some module import versioning errors or something weird).

https://github.com/namehash/ensnode/blob/main/packages/ponder-subgraph-api/src/middleware.ts

Because of this, we also don't have access to the internal metadatastore necessary to power the _meta field, which is necessary for full subgraph-compatibility.

Proposed solution

I'd love to be able to pass a built graphql schema to the ponder middleware. The change could be an additional optional argument in middleware.ts of graphqlSchema, defaulting to buildGraphQLSchema({ schema }) as it is currently.

This would allow our custom schema to access metadata store through the graphql schema context, and we wouldn't have to copy/paste the middleware.ts just to replace that line.

@kyscott18
Copy link
Collaborator

Seems like a very reasonable feature to add.

Would the graphqlSchema and schema params be mutually exclusive? Also, if you are just trying to get access to metadataStore there are some available globals that you could use.

declare global {
var PONDER_NAMESPACE_BUILD: NamespaceBuild;
var PONDER_INDEXING_BUILD: IndexingBuild;
var PONDER_DATABASE: Database;
}

@shrugs
Copy link
Contributor Author

shrugs commented Feb 13, 2025

happy to wait for a more direct integration with metadatastore for the moment — not a blocking issue on our end just yet.

it does seem that schema and graphqlSchema would be mutually exclusive. and requiring every user to pass graphql({ schema: buildGraphQLSchema({ schema }) }) seems annoying and a breaking change.

@typedarray
Copy link
Collaborator

What do you think of upstreaming the (best-effort) subgraph-compatible GraphQL option to the framework? We'd gladly include + document it as an option alongside the Ponder one. Also down to collab on a third-party library if you'd prefer.

Here are a few API options off the top of my head:

import { db } from "ponder:api";
import schema from "ponder:schema";
import { Hono } from "hono";
import { client, graphql } from "ponder";

const app = new Hono();

// Existing API
app.use("/graphql", graphql({ db, schema }));

// 1) New mode on existing middleware
app.use("/graphql", graphql({ db, schema, mode: "subgraph" }));

// 2) New middleware
import { subgraphGraphql } from "ponder"; // or from "your-library"
app.use("/graphql", subgraphGraphql({ db, schema }));

// 3) Use `graphql` schema objects as shared interface
import { buildPonderGraphqlSchema, buildSubgraphGraphqlSchema } from "ponder";

const ponderGraphqlSchema = buildPonderGraphqlSchema({ schema })
const subgraphGraphqlSchema = buildSubgraphGraphqlSchema({ schema })

app.use("/ponder-graphql", graphql({ db, graphqlSchema: ponderGraphqlSchema }));
app.use("/subgraph-graphql", graphql({ db, graphqlSchema: subgraphGraphqlSchema }));

export default app;

It's possible to achieve option 3 without a breaking change, and we could prob make it more concise. FWIW, it's always been a backburner design goal to push more and more of the GraphQL stuff into userland, so I generally like option 3.

@shrugs
Copy link
Contributor Author

shrugs commented Feb 13, 2025

I think we're happy to upstream it, though I worry about the maintenance cost of that file, as it is a bit unruly. but once it's at a comfortable place with the ens testing suite & querying expectations (ETA end of feb?) we could definitely propose a pr. not sure how much code we might want to share between the implementations yet.

i like options 1 and 2, both seem quite reasonable and backwards compatible. option 3 seems like too much config to make every user go through and requires a small code update.

@typedarray
Copy link
Collaborator

Ok, sounds good. Let us know if you need any help navigating the internals, a prerelease to make something available, etc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants