Upgrade From 5.6.0 to 5.7.0
Learn how to upgrade Webiny from 5.6.0 to 5.7.0.
- how to upgrade Webiny from 5.6.0 to 5.7.0
Upgrade Webiny Packages
The first step is to upgrade all @webiny/*
packages, which can be done by running the following command in the root of your project:
# Execute in your project root.
yarn up "@webiny/*@5.7.0"
Once the packages upgrade has finished, running the yarn webiny --version
command in your terminal should return 5.7.0
.
Upgrade Lambda Handlers
In order to benefit from the new API Error Overlay feature, we need to add some tweaks to the configuration of our Lambda handlers.
graphql
Lambda Handler
In your api/code/graphql/src/index.ts
file, add a debug
variable and modify the call to createHandler
to use a configuration object:
// your existing import statements
const debug = process.env.DEBUG === "true";
export const handler = createHandler({
plugins: [
// your existing plugins
],
http: { debug }
});
Also change the graphqlPlugins({ debug: process.env.DEBUG })
to graphqlPlugins({ debug })
, as we’re now very strict about the type of debug
parameter (it now has to be a boolean). That’s why we explicitly define that variable once, and reuse it where needed.
As you can see, we now use a configuration object to explicitly pass plugins
and other parameters required by the Lambda handler factory package. The http: { debug }
will be passed all the way to the internal @webiny/handler-http package which will handle the errors for us.
If unsure what the final result should look like, please see the original file for a complete example.
headlessCMS
Lambda Handler
The same change applies to headlessCMS
Lambda. In your api/code/headlessCMS/src/index.ts
file, add a debug
variable and modify the call to createHandler
to use a configuration object:
// your existing import statements
const debug = process.env.DEBUG === "true";
export const handler = createHandler({
plugins: [
// your existing plugins
],
http: { debug }
});
If unsure what the final result should look like, please see the original file for a complete example.
Upgrade React Applications
Upgrade admin
Application
Open your apps/admin/code/src/components/apolloClient.ts
file and replace everything with the following:
import ApolloClient from "apollo-client";
import { ApolloLink } from "apollo-link";
import { BatchHttpLink } from "apollo-link-batch-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import { plugins } from "@webiny/plugins";
import { ApolloDynamicLink } from "@webiny/app/plugins/ApolloDynamicLink";
import { CacheGetObjectIdPlugin } from "@webiny/app/types";
export const createApolloClient = ({ uri }) => {
return new ApolloClient({
link: ApolloLink.from([
/**
* This will process links from plugins on every request
*/
new ApolloDynamicLink(),
/**
* This batches requests made to the API to pack multiple requests into a single HTTP request.
*/
new BatchHttpLink({ uri })
]),
cache: new InMemoryCache({
addTypename: true,
dataIdFromObject: obj => {
/**
* Since every data type coming from API can have a different data structure,
* we cannot rely on having an `id` field.
*/
const getters = plugins.byType<CacheGetObjectIdPlugin>("cache-get-object-id");
for (let i = 0; i < getters.length; i++) {
const id = getters[i].getObjectId(obj);
if (typeof id !== "undefined") {
return id;
}
}
/**
* As a fallback, try getting object's `id`.
*/
return obj.id || null;
}
})
});
};
The important parts are highlighted in the code. We replaced all custom Apollo links with a single ApolloDynamicLink
to handle everything via plugins.
Now we need to register those links we just removed using plugins.
Create a file apps/admin/code/src/plugins/apolloLinks.ts
and paste the following into it:
import { ConsoleLinkPlugin } from "@webiny/app/plugins/ConsoleLinkPlugin";
import { NetworkErrorLinkPlugin } from "@webiny/app/plugins/NetworkErrorLinkPlugin";
import { OmitTypenameLinkPlugin } from "@webiny/app/plugins/OmitTypenameLinkPlugin";
export default [
/**
* This link removes `__typename` from the variables being sent to the API.
*/
new OmitTypenameLinkPlugin(),
/**
* This link checks for presence of `extensions.console` in the response and logs all items to browser console.
*/
new ConsoleLinkPlugin(),
/**
* This plugin creates an ApolloLink that checks for `NetworkError` and shows an ErrorOverlay in the browser.
*/
new NetworkErrorLinkPlugin()
];
Now we just need to import this new file to register them with the application.
Open apps/admin/code/src/plugins/index.ts
, import the new plugins, and register them:
import { plugins } from "@webiny/plugins";
import { WebinyInitPlugin } from "@webiny/app/types";
import welcomeScreenPlugins from "@webiny/app-plugin-admin-welcome-screen";
import routeNotFound from "./routeNotFound";
import basePlugins from "./base";
import apolloLinkPlugins from "./apolloLinks";
import adminPlugins from "./admin";
import i18nPlugins from "./i18n";
import i18nContentPlugins from "./i18nContent";
import securityPlugins from "./security";
import pageBuilderPlugins from "./pageBuilder";
import formBuilderPlugins from "./formBuilder";
import headlessCmsPlugins from "./headlessCms";
import theme from "theme";
plugins.register([
/**
* Base app plugins (files, images).
*/
basePlugins,
/**
* ApolloClient link plugins.
*/
apolloLinkPlugins,
/**
* Complete admin app UI.
*/
adminPlugins,
/**
* Renders a welcome screen with useful links at "/".
*/
welcomeScreenPlugins(),
/**
* Handles location paths that don't have a corresponding route.
*/
routeNotFound,
/**
* Internationalization app.
*/
i18nPlugins,
/**
* Enables storing content (pages, forms, content, ...) in multiple locales.
*/
i18nContentPlugins,
/**
* Security app and authentication plugins.
*/
securityPlugins,
/**
* Page Builder app.
*/
pageBuilderPlugins,
/**
* Form Builder app.
*/
formBuilderPlugins,
/**
* Headless CMS app.
*/
headlessCmsPlugins,
/**
* App theme controls page builder and form builder layouts, styles, etc.
*/
theme()
]);
plugins.byType<WebinyInitPlugin>("webiny-init").forEach(plugin => plugin.init());
Upgrade website
Application
Open apps/website/code/src/components/apolloClient.ts
and replace everything with the following code:
import ApolloClient from "apollo-client";
import { ApolloLink } from "apollo-link";
import { BatchHttpLink } from "apollo-link-batch-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloDynamicLink } from "@webiny/app/plugins/ApolloDynamicLink";
export const createApolloClient = () => {
const isProduction = process.env.NODE_ENV === "production";
const cache = new InMemoryCache({
addTypename: true,
dataIdFromObject: obj => obj.id || null
});
if (isProduction && process.env.REACT_APP_ENV === "browser") {
// Production build of this app will be rendered using SSR so we need to restore cache from pre-rendered state.
// @ts-ignore
cache.restore(window.__APOLLO_STATE__);
}
// @ts-ignore
cache.restore("__APOLLO_STATE__" in window ? window.__APOLLO_STATE__ : {});
const uri = process.env.REACT_APP_GRAPHQL_API_URL;
const link = ApolloLink.from([new ApolloDynamicLink(), new BatchHttpLink({ uri })]);
// @ts-ignore
window.getApolloState = () => {
// @ts-ignore
return cache.data.data;
};
return new ApolloClient({ link, cache });
};
Lastly, open apps/website/code/src/plugins/apolloLinks.ts
and replace everything with the following code:
import { OmitTypenameLinkPlugin } from "@webiny/app/plugins/OmitTypenameLinkPlugin";
import { LocaleHeaderLinkPlugin } from "@webiny/app/plugins/LocaleHeaderLinkPlugin";
import { TenantHeaderLinkPlugin } from "@webiny/app/plugins/TenantHeaderLinkPlugin";
export default () => [
/**
* This link removes `__typename` from the variables being sent to the API.
*/
new OmitTypenameLinkPlugin(),
/**
* Append `x-tenant` header from URL query (necessary for prerendering service).
*/
new TenantHeaderLinkPlugin(),
/**
* Append `x-i18n-locale` header from URL query (necessary for prerendering service).
*/
new LocaleHeaderLinkPlugin()
];