pothos
pothos copied to clipboard
wip - Pothos EdgeDB Plugin
WIP EdgeDB Plugin
Related Issue: https://github.com/hayes/pothos/issues/534
edgeDBObject
Naming Conventions
-
t.link()
: Model property which is a relation to another model. (like prisma pluginst.relation()
) Could be one or many relation to model.
Open for any feedback and reviews!
⚠️ No Changeset found
Latest commit: 8ec9e25d91d12fa9059a8ec0314c8b493944444e
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
The latest updates on your projects. Learn more about Vercel for Git ↗︎
Name | Status | Preview | Updated |
---|---|---|---|
pothos | ✅ Ready (Inspect) | Visit Preview | Aug 22, 2022 at 2:40PM (UTC) |
Current work only covers the edgeDBObject
api. Showcase of how the type system could look like for the edgeDB schema. Type system is constructed out of the EdgeDB Query Builder types, specifically from the default export type. Output shape looks pretty similar to the PrismaTypes shape

This looks like an awesome start! Getting the type system working is often one of the hardest parts, and it looks like you are making great progress!
I'll try to find some time today to dive a little deeper. Initial skim looks like there are lots of pieces that are unused or copied from the prisma plugin that don't quite make sense yet, so I'll just ignore those for now and try to look specifically at types for defining objects and links
Curious about your goals here, and what you are looking for. Is this something you want to get merged in the not too distant future, or more just sharing/collecting feedback while you iterate?
Long term, is this something you want have live in the main repo and have maintained with the rest of the plugins, or something you want to own in your own repo. I have been meaning to create some docs pages for linking out to community maintained projects. It might also be interesting do have a model similar to https://github.com/opentracing-contrib where there is an official place for people to add their own plugins/packages/examples etc in a way that is discoverable.
Open to any ideas and suggestions here, and don't feel too strongly about it. I would say that the bar for what I would expect in this repo would likely be a lot higher, and include things like making sure that this works well with all the other plugins, thorough documentation, test coverage, and solutions for things like aliasing fields, or defining multiple fields that use the same link
in the database.
Regardless of how you want to work on this, and where you would like it to live, I am happy to help out when I have time, and give feedback/reviews or answer any questions you have about how the internals of pothos work. Looks like you are already making a lot of progress and have figured out a lot of the weird patterns needed to make something like this work.
Agreed, this is right now just not enough for a plugin imo. Long term I would love to see it in the main repo as a plugin. But also looking for more features, supporting other plugins and enabling integrations, like relay nodes and so on. A lot of work needs to be done, not finished at all.
I am not very familiar with the architecture and type system of Pothos, still learning the patterns and experimenting with the types :)
I was porting a lot of the prisma plugins system into this plugin therefore still unused and unnecessary code / type definitions around here. Will clean that up.
Will need some feedback on this topic.
Edgedb queries return type depends on the select shape. Even ...e.User["*"]
won't load the whole db schema. That would be a problem for edgeDBField
resolve functions return type since Model["Shape"]
won't be the return type at any time. Instead the return type needs to be composed of optional fields. We might not wanna loose the actual nullability of model properties in Model["Shape"]
, important for edgeDBObject
field definitions. So defining another Shape
type as the optional reflection looks like a solution.
Example
// EdgeDB Generated QueryBuilder
import e from '../../client';
builder.queryType({
fields: (t) => ({
users: t.edgeDBField({
type: ['User'],
nullable: true,
resolve: async (_query, _parent, _args, ctx) => {
const users = await e
.select(e.User, (user) => ({
id: true,
email: true,
name: true,
}))
.run(db);
return users;
// ^? { id: string; email:string; name: string | null; }[]
// This would not match with Users Model["Shape"], comments | posts ... are missing
},
}),
}),
});
interface EdgeDBModelTypes {
User: {
Shape: {
"comments": Comment[];
"posts": Post[];
"email": string;
"name"?: string | null;
"followers": Follow[];
"following": Follow[];
"media": Media[];
"profile"?: Profile | null;
}
}
}
Added ReturnShape
to reflect Shape
props as optional fields.
https://github.com/hayes/pothos/blob/f853b76a8a0bc58ec6fa9b4578bb7aa706515958/packages/plugin-edgedb/src/types.ts#L80-L86
https://github.com/hayes/pothos/blob/f853b76a8a0bc58ec6fa9b4578bb7aa706515958/packages/plugin-edgedb/src/global-types.ts#L102-L104
Added
ReturnShape
toEdgeDBModelTypes
to reflect optional fields fromShape
.https://github.com/hayes/pothos/blob/f853b76a8a0bc58ec6fa9b4578bb7aa706515958/packages/plugin-edgedb/src/types.ts#L80-L86
Actually supposed to be a deep partial type, updated version:
https://github.com/baristikir/giraphql/blob/8ec9e25d91d12fa9059a8ec0314c8b493944444e/packages/plugin-edgedb/src/types.ts#L72-L88
Edgedb queries return type depends on the select shape. Even ...e.User["*"] won't load the whole db schema. That would be a problem for edgeDBField resolve functions return type since Model["Shape"] won't be the return type at any time. Instead the return type needs to be composed of optional fields. We might not wanna loose the actual nullability of model properties in Model["Shape"], important for edgeDBObject field definitions. So defining another Shape type as the optional reflection looks like a solution.
I think the technically correct approach here would be to model this after the "select" mode from the prisma plugin. Basically the prisma plugin supports having a default set of selections defined on the "prismaObject", when you do this, the "parent" type for all resolvers is limited to that selection. You can still "expose" fields that are not part of the selection (which will automatically select them when the expsosed field is queried) . You can then also define selections on individual fields, which will extend the parent type in the resolver for that field.
You can see an example of this here: https://github.com/hayes/pothos/blob/main/packages/plugin-prisma/tests/example/schema/index.ts#L38-L59
The implementation for this gets a lot more complicated, so not sure if you need to explore this in the initial version. Took me a few iterations of the prisma plugin before I figured out how to make that work properly.