
Security News
PEP 810 Proposes Explicit Lazy Imports for Python 3.15
An opt-in lazy import keyword aims to speed up Python startups, especially CLIs, without the ecosystem-wide risks that sank PEP 690.
graphql-auto-federate
Advanced tools
Automatically federate a GraphQL service
const fastify = require('fastify')
const mercurius = require('mercurius')
const { buildFederatedService } = require('graphql-auto-federate')
const federated = await buildFederatedService({
url: `http://original-service:1234/graphql`
})
const federatedService = fastify()
federatedService.register(mercurius, {
...federated,
federationMetadata: true,
jit: 1
})
await federatedService.listen(3001)
const gateway = fastify()
gateway.register(mercurius, {
services: [{ name: 'auto', url: `http://localhost:3001/graphql` }],
jit: 1
})
await gateway.listen(3000)
// query the gateway @ port 3000
// curl -X POST -H 'content-type: application/json' -d '{ "query": "{ hello(greeting: \"ciao\") }" }' localhost:3000/graphql
Given an existing GraphQL service, graphql-auto-federate
reads the schema and builds a new service with federation information that acts as a proxy, forwarding requests to the original service:
( gateway ) --> ( federated "proxy" service ) --> ( original service )
graphql-auto-federate
discovers as much information as possible from the original service schema, but additional information is typically required for a working federated service.
This can be achieved by specifying __resolveReference
resolvers and directives for entity types (see options).
The __resolveReference
resolver is critical for a working federated service. Implementing __resolveReference
for entities in this context (a "proxy" to federate an existing service) is not trivial and strongly depends on the schema and entities provided by the original service.
A special forward
function is provided along with the regular resolver arguments to facilitate querying the original service (errors are already managed).
options: {
resolvers: {
User: {
__resolveReference: async (self, args, context, info, forward) => {
const response = await forward({
query: `{ getUser (id: ${self.id}) { name, fullName } }`
})
return {
...response.getUser,
...self
}
}
}
}
}
Note: in some cases, __resolveReference
is redundant, for example in Query
resolvers, the original service provides all of the required information without needing to call __resolveReference
again.
buildFederatedService ({ url, options }) => { schema, resolvers }
Creates the { schema, resolvers }
information to build the federated service.
It performs an introspection query
to the original service, then augments the schema to produce a federated schema
and resolvers
.
options
should contain additional information for type
and resolvers
, that are merged and override those that are discovered.
From the original service schema:
type Query {
getUser(id: ID!): User
getUsers: [User]!
}
type Mutation {
createUser(user: InputUser): User
updateUser(id: ID!, user: InputUser): User
deleteUser(id: ID!): ID
}
input InputUser {
name: String!
}
type User {
id: ID!
name: String!
fullName: String
friends: [User]
}
const { schema, resolvers } = await buildFederatedService({
url: `http://original-service:1234/graphql`
})
Generated federated schema is:
extend type Query {
getUser(id: ID!): User
getUsers: [User]!
}
extend type Mutation {
createUser(user: InputUser): User
updateUser(id: ID!, user: InputUser): User
deleteUser(id: ID!): ID
}
input InputUser {
name: String!
}
type User @key(fields: "id") {
id: ID!
name: String!
fullName: String
friends: [User]
}
Generated federated resolvers are:
{
Query: {
getUser: (...) => // forward query
getUsers: (...) => // forward query
},
Mutation: {
createUser: (...) => // forward query
updateUser: (...) => // forward query
deleteUser: (...) => // forward query
},
User: {
__resolveReference: (self) => { console.warn('__resolveReference called', self) }
}
}
the url
of the original GraphQL service
auto
option discovers the schema from the original service and builds the relative federated schema
and resolvers
(default: true
)
Inject information to the type definition schema, adding @extend
or @directives
for entity types. These are merged with (and override) the auto
discovered ones if any.
@extend
(boolean) add "extend" to the type@directives
(string) add directives as a string to the type, see federation spec for supported directivesFrom original service schema:
type Query {
getUser(id: ID!): User
getUsers: [User]!
}
type User {
id: ID!
name: String!
fullName: String
}
Using options:
options: {
auto: false,
type: {
Query: {
'@extend': true
},
User: {
'@directives': '@key(fields: "id") @external'
}
}
}
Generated federated schema:
extend type Query {
getUser(id: ID!): User
getUsers: [User]!
}
type User @key(fields: "id") @external {
id: ID!
name: String!
fullName: String
}
Provide resolvers
, these are merged with (and override) the auto
discovered ones if any.
Automatic generation of federated schema supports
options.loaders
graphqlRequest
__resolveReference
resolution
context.__currentQuery
?)__resolveReference
if not necessary__resolveReference
- { query, variables, transform (jsonata) }
buildFederatedInfo
and document itFAQs
Automatically federate a GraphQL service
We found that graphql-auto-federate demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
An opt-in lazy import keyword aims to speed up Python startups, especially CLIs, without the ecosystem-wide risks that sank PEP 690.
Security News
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.