This guide helps you migrate to the next version of the SDK
The "next" version of the SDK is a major step forward to our open source release. It comes with a few small breaking changes and lots of improvements.
Prerequisites#
First, make sure you're using wunderctl 0.74.5 or later.
Next, follow the instructions below to migrate to the new format.
1. Update the dependencies#
yarn add @wundergraph/sdk@next# ornpm install @wundergraph/sdk@next
The @wundergraph/sdk
should be updated to the latest version tagged with next
, currently 1.0.0-next.15
.
2. Remove package.json and node_modules from .wundergraph directory#
It's no longer necessary to have an embedded node_modules directory.
If you're using wundergraph as a sub directory inside your project,
you can remove the package.json, yarn.lock and node_modules directory from the .wundergraph
directory.
If you've just got a single directory without a .wundergraph
directory,
you can ignore this step.
3. Remove the generated directory#
With the new version of the SDK, the generated directory can be removed. It's also no longer necessary to commit it, keeping your git project clean.
rm -rf .wundergraph/generated
Now add .wundergraph/generated
to your .gitignore file and commit the changes.
echo ".wundergraph/generated" >> .gitignore
Once this is done, you can re-generated the directory.
4. Rename wundergraph.hooks.ts
to wundergraph.server.ts
#
With the "next" version of the SDK, it's possible to not just have hooks but also custom GraphQL resolvers. This way, you're able to extend your Virtual Graph with custom GraphQL Schemas and resolvers, giving you 100% flexibility in writing your business logic.
mv wundergraph.hooks.ts wundergraph.server.ts
5. Fix wundergraph.server.ts
#
Next, we have to modify the imports in wundergraph.server.ts
to reflect the new version of the SDK.
The following imports are no longer valid:
import {configureWunderGraphHooksWithClient} from './generated/wundergraph.hooks.configuration'
Replace them with the following:
import {configureWunderGraphServer} from "@wundergraph/sdk";import type {HooksConfig} from "./generated/wundergraph.hooks";import type {InternalClient} from "./generated/wundergraph.internal.client";import type {GraphQLExecutionContext} from "./generated/wundergraph.server"
You'll notice that we're using import type
instead of import
to avoid the compiler complaining about the missing types.
This way, we're able to compile the code without the types,
which get generated after the first compilation step.
Next, we have to replace the usage of configureWunderGraphHooksWithClient
with configureWunderGraphServer
.
The following code is no longer valid:
const wunderGraphHooks = configureWunderGraphHooksWithClient(client => ({queries: {},mutations: {},}));
Replace it with the following:
export default configureWunderGraphServer<HooksConfig,InternalClient>((serverContext) => ({hooks: {queries: {},mutations: {},},}));
A few things to notice.
First, configureWunderGraphServer
takes two generic parameters, the HooksConfig
and the InternalClient
.
These are the two types we're importing from the generated code.
Next, the configuration function takes a serverContext
object.
This object gives you access the internal client, which allows you to call your pre-defined GraphQL queries and mutations.
Finally, if you had hooks configured before in the root object, you'll have to move them into the hooks
object.
This is because additionally to hooks, you're now also able to configure your custom GraphQL resolvers.
6. Fix wundergraph.operations.ts
#
The imports and configuration functions also changed in wundergraph.operations.ts
so that the compiler can work without the generated directory.
The following imports are no longer valid:
import {configureWunderGraphOperations,MutationConfiguration,QueryConfiguration, SubscriptionConfiguration} from "./generated/wundergraph.operations.configuration";
Replace them with the following:
import {configureWunderGraphOperations} from "@wundergraph/sdk";import type { OperationsConfiguration } from "./generated/wundergraph.operations";
The function to configure the operations needs to change as well. Here's the obsolete code:
const operations = configureWunderGraphOperations({defaultConfig: {authentication: {required: false}},queries: config => config,mutations: config => config,subscriptions: config => config,custom: {}});export default operations;
Replace it with the following snippet:
export default configureWunderGraphOperations<OperationsConfiguration>({operations: {defaultConfig: {authentication: {required: false}},queries: config => ({...config,caching: {enable: false,staleWhileRevalidate: 60,maxAge: 60,public: true},liveQuery: {enable: true,pollingIntervalSeconds: 1,}}),mutations: config => ({...config,}),subscriptions: config => ({...config,}),custom: {}}});
The config for "operations" has an extra namespace on the root object (operations), to allow us to extend it easily later on without breaking changes.
Additionally, the configuration function now takes a generic type parameter. This is to achieve type safety without having the compiler complain if the generated directory is empty.
7. Add a custom GraphQL resolver#
Make the following changes to your wundergraph.server.ts
file:
import {GraphQLObjectType,GraphQLSchema,GraphQLString} from "graphql";export default configureWunderGraphServer<HooksConfig,InternalClient>((serverContext) => ({hooks: {queries: {},mutations: {},},graphqlServers: [{apiNamespace: "public",serverName: "public",enableGraphQLEndpoint: true,schema: new GraphQLSchema({query: new GraphQLObjectType<any, GraphQLExecutionContext>({name: 'Query',fields: {hello: {type: GraphQLString,resolve() {return 'world';},},},}),})}],}));
If required, add the "graphql" package to your dependencies, the version should be "15.8.0
.
This adds a fully custom GraphQL Server to your "public" namespace in the "Virtual Graph".
You might have noticed that we've injected the GraphQLExecutionContext
into the resolve
function.
This generic will allow you to access the context object from all your resolvers.
The context object will contain the user Object, if they are logged in,
as well as the original client request.
This way, you have 100% flexibility in writing your business logic, and you can use the context object to access the user, the request, etc.
8. Update the wundergraph.config.ts
file#
Now onto the final step, we have to slightly update the wundergraph.config.ts
file.
This import needs to be removed:
import wunderGraphHooks from "./wundergraph.hooks";
We have to replace it with the following:
import server from "./wundergraph.server";
Additionally, we have to modify the function call of configureWunderGraphApplication
:
This is no longer valid:
configureWunderGraphApplication({application: myApplication,hooks: wunderGraphHooks.config,operations,});
Replace it with the following:
configureWunderGraphApplication({application: myApplication,server,operations,});
We directly pass the server
object to the configureWunderGraphApplication
function.
9. Run your WunderGraph Environment#
That's it! You're now ready to run your migrated WunderGraph Environment.
Debug mode:
wunderctl up --debug
Production mode:
wunderctl start
Code-Generation Only:
wunderctl generate
Summary and Checklist#
What looks like a lot of work can actually be done in a few minutes.
Here's a checklist for you to go through to make sure everything is working as expected:
- install at least wunderctl version 0.73.0
- update the WunderGraph SDK to
@wundergraph/sdk@next
- remove
.wundergraph/generated
from your git repository - rename
wundergraph.hooks.ts
towundergraph.server.ts
- fix imports and function calls in
wundergraph.server.ts
- fix imports and function calls in
wundergraph.operations.ts
- add a custom GraphQL Schema & resolver to
wundergraph.server.ts
if you want to - fix imports and function calls in
wundergraph.config.ts
- run WunderGraph
Note on running in production#
You might be using wunderctl start
to start your application in production.
We've improved the bundling process so that modules from the node_modules
folder are not bundled anymore.
This makes your IDE much more comfortable to use, as it doesn't have to index all the bundled code.
As a consequence, it's mandatory that you copy over the node_modules
folder into your production environment.
E.g. if you're building a docker container, make sure to copy the over the node_modules
folder.
The simples way to achieve this is by running npm install
during the build process and then copy over the whole .wundergraph
directory.
You'll also notice that wunderctl start
needs to be run from the .wundergraph
directory.
Before this change, you had to run it from the .wundergraph/generated
directory.
Useful links#
If you need an example of how to add a custom GraphQL Schema & resolver, you can check out the Realtime Chat Example.
It's also showing that you can access the client request and User object from within the resolver context.