Skip to Content

This guide helps you migrate to the next version of the SDK

Published: 2022-05-23

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
# or
npm 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:

  1. install at least wunderctl version 0.73.0
  2. update the WunderGraph SDK to @wundergraph/sdk@next
  3. remove .wundergraph/generated from your git repository
  4. rename wundergraph.hooks.ts to wundergraph.server.ts
  5. fix imports and function calls in wundergraph.server.ts
  6. fix imports and function calls in wundergraph.operations.ts
  7. add a custom GraphQL Schema & resolver to wundergraph.server.ts if you want to
  8. fix imports and function calls in wundergraph.config.ts
  9. 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.

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.


Product

Comparisons

Subscribe to our newsletter!

Stay informed when great things happen! Get the latest news about APIs, GraphQL and more straight into your mailbox.

© 2022 WunderGraph