universal-react-apollo
v2.0.3
Published
Lightweight wrapper library around react-apollo and apollo-server-express to build universal (isomorphic) app with less boilerplate
Downloads
10
Maintainers
Readme
Universal React Apollo
Universal React Apollo is a lightweight wrapper library around @apollo-client and apollo-server-express to make it easy to build an universal app and reduce boilerplate code.
Installation
Install universal-react-apollo
and all its peer dependencies
npm install -S universal-react-apollo react react-dom @apollo/client @graphql-tools/schema graphql apollo-server-express express
⚠️ react-apollo
related packages has removed from peerDependencies as of [email protected]
due to @apollo/client migration. Please run the command below if you decide to use [email protected]⚠️
npm install -S universal-react-apollo react react-dom apollo-client apollo-cache-inmemory apollo-link-http apollo-link-schema react-apollo graphql-tag graphql-tools graphql apollo-server-express express
Usage
Step 1: Server side setup
- Define the route setting of your application
// file: routes.js
import React from "react";
import HomeApp from "./pages/home/app";
export default [
{
method: "get", // default is get if this field is not defined
path: "/home",
htmlTagAttrs: { lang: "en-GB" },
appElement: ({ req }) => <HomeApp />,
headElement: ({ req }) => <title>Home</title>,
bodyBottomElement: ({ req }) => <script src="/static/bundle.js"></script>,
},
];
- Initialize the universal (isomorphic) app
// file: server.js
import express from "express";
import cookieParser from "cookie-parser";
import { initServer } from "universal-react-apollo";
import typeDefs from "/path/to/your/gqlSchema";
import resolvers from "/path/to/your/gqlResolvers";
import dataSources from "/path/to/your/gqlDataSources";
import routes from "./routes";
// create express server instance
const app = express();
const apolloOptions = {
typeDefs,
resolvers,
dataSources: () => dataSources,
context: ({ req }) => {
return {
cookies: req.cookies,
};
},
};
// mount additional middleware so that you can get information from request context
app.use(cookieParser());
// mount application routes and apollo server middleware
initServer(app, routes, apolloOptions);
// mount generic server side error handler
app.use(function(err, req, res, next) {
if (res.headersSent) {
return next(err);
}
res.send("Oops... something went wrong");
});
// start server
app.listen(3000, () => console.log("server is running"));
Step 2: Client side setup
Render the universal app in application entry point
// file: index.js
import React from "react";
import clientRender from "universal-react-apollo/clientRender";
import HomeApp from "./pages/home/app";
clientRender(<HomeApp />);
That's it! You have finished building a gql-based universal application.
Error handling
Server side rendering error will be passed to next()
so that you can write your own error middleware function
to handle it. See the error-handling part of Express document for details.
API
initServer(app, routes, apolloOptions, [production])
This function will mount apollo-server-express middleware to the express app instance you passed in and create the application routing handlers according to the route config.
arguments:
| arg | description |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| app | Express app instance |
| routes | An array of route object (see data model section) |
| apolloOptions | Apollo server configuration options |
| production | (optional) Flag indicates that the universal app is running in production mode or not. We use this flag to decide to turn on or off GQL playground
. Default value is false
|
| cors | Cors options. Default value is false
|
clientRender(appElement)
Hydrate the universal app container (reuse server-side generated HTML content and attach event listeners to existing markup).
arguments:
| arg | description | | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | appElement | Main application react element | | inMemoryCacheConfig | apollo client InMemoryCache constructor config object (available options: https://www.apollographql.com/docs/react/advanced/caching/#configuration) |
Data Model
route
fields:
| field | description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| path | Same as Express middleware path argument |
| appElement | A function called with current request that returns a React element you want to render into the app container when the given path is matched |
| method | (optional) The http method of the request. Express app.METHOD supported routing methods are all valid |
| htmlTagAttrs | (optional) Dom attributes of tag |
| headElement | (optional) A function called with current request that returns a React element you want to render into the <head>
tag when the given path is matched |
| bodyBottomElement | (optional) A function called with current request that returns a React element you want to render into the bottom of <body>
tag when the given path is matched |
| middlewareChain | (optional) An array of express middleware function |
| responseStatusCode | (optional) The http status code of response (defaults to 200) |