Schema-first
In standalone graphs, you can define types for your resolvers using the SDK or use GraphQL SDL. You can mix and match based on preference and convenience. Let's look at an example defining a custom resolver and its return type.
First with the SDK only approach:
import { config, graph } from '@grafbase/sdk'
const g = graph.Standalone()
const Invoice = g.type('Invoice', {
id: g.id(),
invoiceNumber: g.string(),
dueDate: g.date(),
totalAmount: g.int(),
})
g.query('invoiceByNumber', {
args: { invoiceNumber: g.string() },
returns: g.ref(Invoice).list(),
resolver: 'invoice/byNumber',
})
export default config({ graph: g })
Now, the same configuration, but defining the field with the custom resolver with the SDK, and its return type in GraphQL:
import { config, graph } from '@grafbase/sdk'
const g = graph.Standalone({
typeDefs: /* GraphQL */ `
type Invoice {
id: ID!
invoiceNumber: String!
dueDate: Date!
totalAmount: Int!
}
`,
})
g.query('invoiceByNumber', {
args: { invoiceNumber: g.string() },
returns: g.ref('Invoice').list(),
resolver: 'invoice/byNumber',
})
export default config({ graph: g })
And finally, the same but defined completely with GraphQL SDL:
import { config, graph } from '@grafbase/sdk'
const g = graph.Standalone({
typeDefs: /* GraphQL */ `
type Invoice {
id: ID!
invoiceNumber: String!
dueDate: Date!
totalAmount: Int!
}
extend type Query {
invoiceByNumber(invoiceNumber: String!): [Invoice!]!
@resolver(name: "invoice/byNumber")
}
`,
})
export default config({ graph: g })