Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
graphql-react
Advanced tools
A GraphQL client for React using modern context and hooks APIs that is lightweight (< 3 KB size limited) but powerful; the first Relay and Apollo alternative with server side rendering.
A GraphQL client for React using modern context and hooks APIs that is lightweight (< 3 KB size limited) but powerful; the first Relay and Apollo alternative with server side rendering.
See the next-graphql-react
setup instructions.
To install graphql-react
from npm run:
npm install graphql-react
Create a single GraphQL
instance and use GraphQLProvider
to provide it for your app.
For server side rendering see ssr()
.
Use the useGraphQL
React hook in your components to make queries and mutations, or use the GraphQL
instance method operate
directly.
Here is a basic example that displays a Pokemon image, with tips commented:
import { GraphQL, GraphQLProvider, useGraphQL } from 'graphql-react';
import React from 'react';
// Zero config GraphQL client that manages the cache.
const graphql = new GraphQL();
const PokemonImage = ({ name }) => {
// The useGraphQL hook can be used just the same for queries or mutations.
const { loading, cacheValue = {} } = useGraphQL({
// Any GraphQL API can be queried in components, where fetch options for
// the URL, auth headers, etc. are specified. To avoid repetition it’s a
// good idea to import the fetch options override functions for the APIs
// your app uses from a central module. The default fetch options received
// by the override function are tailored to the operation; typically the
// body is JSON but if there are files in the variables it will be a
// FormData instance for a GraphQL multipart request.
fetchOptionsOverride(options) {
options.url = 'https://graphql-pokemon.now.sh';
},
// The operation typically contains `query` and sometimes `variables`, but
// additional properties can be used; all are JSON encoded and sent to the
// GraphQL server in the fetch request body.
operation: {
query: `{ pokemon(name: "${name}") { image } }`,
},
// Load the query whenever the component mounts. This is desirable for
// queries to display content, but not for on demand situations like
// pagination view more buttons or forms that submit mutations.
loadOnMount: true,
// Reload the query whenever a global cache reload is signaled.
loadOnReload: true,
// Reload the query whenever the global cache is reset. Resets immediately
// delete the cache and are mostly only used when logging out the user.
loadOnReset: true,
});
return cacheValue.data ? (
<img src={cacheValue.data.pokemon.image} alt={name} />
) : loading ? (
// Data is often reloaded, so don’t assume loading indicates no data.
'Loading…'
) : (
// Detailed error info is available in the `cacheValue` properties
// `fetchError`, `httpError`, `parseError` and `graphQLErrors`. A combination
// of errors is possible, and an error doesn’t necessarily mean data is
// unavailable.
'Error!'
);
};
const App = () => (
<GraphQLProvider graphql={graphql}>
<PokemonImage name="pikachu" />
</GraphQLProvider>
);
^10.17.0 || ^12.0.0 || >= 13.7.0
> 0.5%, not OperaMini all, not dead
Consider polyfilling:
A lightweight GraphQL client that caches queries and mutations.
Parameter | Type | Description |
---|---|---|
options | object? = {} | Options. |
options.cache | GraphQLCache? = {} | Cache to import; usually from a server side render. |
reportCacheErrors
to setup error reporting.Ways to import
.
import { GraphQL } from 'graphql-react';
import GraphQL from 'graphql-react/universal/GraphQL.js';
Ways to require
.
const { GraphQL } = require('graphql-react');
const GraphQL = require('graphql-react/universal/GraphQL');
Construct a GraphQL client.
import { GraphQL } from 'graphql-react';
const graphql = new GraphQL();
Removes an event listener.
Parameter | Type | Description |
---|---|---|
type | string | Event type. |
handler | Function | Event handler. |
Adds an event listener.
Parameter | Type | Description |
---|---|---|
type | string | Event type. |
handler | Function | Event handler. |
reportCacheErrors
can be used with this to setup error reporting.Loads or reuses an already loading GraphQL operation in GraphQL operations. Emits a GraphQL
instance fetch
event if an already loading operation isn’t reused, and a cache
event once it’s loaded into the GraphQL cache.
Parameter | Type | Description |
---|---|---|
options | object | Options. |
options.operation | GraphQLOperation | GraphQL operation. |
options.fetchOptionsOverride | GraphQLFetchOptionsOverride? | Overrides default GraphQL operation fetch options. |
options.reloadOnLoad | boolean? = false | Should a GraphQL reload happen after the operation loads, excluding the loaded operation cache. |
options.resetOnLoad | boolean? = false | Should a GraphQL reset happen after the operation loads, excluding the loaded operation cache. |
Returns: GraphQLOperationLoading — Loading GraphQL operation details.
Signals that GraphQL cache subscribers such as the useGraphQL
React hook should reload their GraphQL operation.
Parameter | Type | Description |
---|---|---|
exceptCacheKey | GraphQLCacheKey? | A GraphQL cache key for cache to exempt from reloading. |
Reloading the GraphQL cache.
graphql.reload();
Resets the GraphQL cache, useful when a user logs out.
Parameter | Type | Description |
---|---|---|
exceptCacheKey | GraphQLCacheKey? | A GraphQL cache key for cache to exempt from deletion. Useful for resetting cache after a mutation, preserving the mutation cache. |
Resetting the GraphQL cache.
graphql.reset();
Cache of loaded GraphQL operations. You probably don’t need to interact with this unless you’re implementing a server side rendering framework.
Type: GraphQLCache
Export cache as JSON.
const exportedCache = JSON.stringify(graphql.cache);
Example cache JSON.
{
"a1bCd2": {
"data": {
"viewer": {
"name": "Jayden Seric"
}
}
}
}
A map of loading GraphQL operations. You probably don’t need to interact with this unless you’re implementing a server side rendering framework.
Type: object<GraphQLCacheKey, Promise<GraphQLCacheValue>>
Signals that a GraphQL operation was fetched and cached.
Type: object
Property | Type | Description |
---|---|---|
cacheKey | GraphQLCacheKey | The GraphQL cache key for the operation that was cached. |
cacheValue | GraphQLCacheValue | The loaded GraphQL cache value. |
response | Response? | The Response instance; may be undefined if there was a fetch error. |
Signals that a GraphQL operation is being fetched.
Type: object
Property | Type | Description |
---|---|---|
cacheKey | GraphQLCacheKey | The GraphQL cache key for the operation being fetched. |
cacheValuePromise | Promise<GraphQLCacheValue> | Resolves the loaded GraphQL cache value. |
Signals that GraphQL cache subscribers such as the useGraphQL
React hook should reload their GraphQL operation.
Type: object
Property | Type | Description |
---|---|---|
exceptCacheKey | GraphQLCacheKey? | A GraphQL cache key for cache to exempt from reloading. |
Signals that the GraphQL cache has been reset.
Type: object
Property | Type | Description |
---|---|---|
exceptCacheKey | GraphQLCacheKey? | The GraphQL cache key for cache that was exempted from deletion. |
A React component that provides a GraphQL
instance for an app.
Parameter | Type | Description |
---|---|---|
props | object | Component props. |
props.graphql | GraphQL | GraphQL instance. |
props.children | ReactNode? | React children. |
Returns: ReactNode — React virtual DOM node.
GraphQLContext
is provided via this component.useGraphQL
React hook requires this component to be an ancestor to work.Ways to import
.
import { GraphQLProvider } from 'graphql-react';
import GraphQLProvider from 'graphql-react/universal/GraphQLProvider.js';
Ways to require
.
const { GraphQLProvider } = require('graphql-react');
const GraphQLProvider = require('graphql-react/universal/GraphQLProvider');
Provide a GraphQL
instance for an app.
import { GraphQL, GraphQLProvider } from 'graphql-react';
import React from 'react';
const graphql = new GraphQL();
const App = ({ children }) => (
<GraphQLProvider graphql={graphql}>{children}</GraphQLProvider>
);
A GraphQL
event cache
handler that reports fetch
, HTTP, parse and GraphQL errors via console.log()
. In a browser environment the grouped error details are expandable.
Parameter | Type | Description |
---|---|---|
data | GraphQL#event:cache | GraphQL cache event data. |
Ways to import
.
import { reportCacheErrors } from 'graphql-react';
import reportCacheErrors from 'graphql-react/universal/reportCacheErrors.js';
Ways to require
.
const { reportCacheErrors } = require('graphql-react');
const reportCacheErrors = require('graphql-react/universal/reportCacheErrors');
GraphQL
initialized to report cache errors.
import { GraphQL, reportCacheErrors } from 'graphql-react';
const graphql = new GraphQL();
graphql.on('cache', reportCacheErrors);
Asynchronously server side renders a React node, preloading all GraphQL queries set to loadOnMount
. After resolving, cache can be exported from the GraphQL
instance property cache
for serialization (usually to JSON) and transport to the client for hydration via the GraphQL
constructor parameter options.cache
.
Be sure to globally polyfill fetch
.
Parameter | Type | Description |
---|---|---|
graphql | GraphQL | GraphQL instance. |
node | ReactNode | React virtual DOM node. |
render | Function? = ReactDOMServer.renderToStaticMarkup | Synchronous React server side render function, defaulting to ReactDOMServer.renderToStaticMarkup as it is more efficient than ReactDOMServer.renderToString . |
Returns: Promise<string> — Promise resolving the rendered HTML string.
ReactDOMServer
docs.next-graphql-react
to use this API in a Next.js project.Ways to import
.
import { ssr } from 'graphql-react/server';
import ssr from 'graphql-react/server/GraphQL.js';
Ways to require
.
const { ssr } = require('graphql-react/server');
const ssr = require('graphql-react/server/ssr');
SSR function that resolves a HTML string and cache JSON for client hydration.
import { GraphQL, GraphQLProvider } from 'graphql-react';
import { ssr } from 'graphql-react/server';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { App } from './components/App.mjs';
async function render() {
const graphql = new GraphQL();
const page = (
<GraphQLProvider graphql={graphql}>
<App />
</GraphQLProvider>
);
const html = await ssr(graphql, page, ReactDOMServer.renderToString);
const cache = JSON.stringify(graphql.cache);
return { html, cache };
}
SSR function that resolves a HTML string suitable for a static page.
import { GraphQL, GraphQLProvider } from 'graphql-react';
import { ssr } from 'graphql-react/server';
import React from 'react';
import { App } from './components/App.mjs';
function render() {
const graphql = new GraphQL();
const page = (
<GraphQLProvider graphql={graphql}>
<App />
</GraphQLProvider>
);
return ssr(graphql, page);
}
A React hook to manage a GraphQL operation in a component.
Parameter | Type | Description |
---|---|---|
options | object | Options. |
options.fetchOptionsOverride | GraphQLFetchOptionsOverride? | Overrides default fetch options for the GraphQL operation. |
options.loadOnMount | boolean? = false | Should the operation load when the component mounts. |
options.loadOnReload | boolean? = false | Should the operation load when the GraphQL reload event fires and there is a GraphQL cache value to reload, but only if the operation was not the one that caused the reload. |
options.loadOnReset | boolean? = false | Should the operation load when the GraphQL reset event fires and the GraphQL cache value is deleted, but only if the operation was not the one that caused the reset. |
options.reloadOnLoad | boolean? = false | Should a GraphQL reload happen after the operation loads, excluding the loaded operation cache. |
options.resetOnLoad | boolean? = false | Should a GraphQL reset happen after the operation loads, excluding the loaded operation cache. |
options.operation | GraphQLOperation | GraphQL operation. |
Returns: GraphQLOperationStatus — GraphQL operation status.
GraphQLContext
is required for this hook to work.Ways to import
.
import { useGraphQL } from 'graphql-react';
import useGraphQL from 'graphql-react/universal/useGraphQL.js';
Ways to require
.
const { useGraphQL } = require('graphql-react');
const useGraphQL = require('graphql-react/universal/useGraphQL');
A component that displays a Pokémon image.
import { useGraphQL } from 'graphql-react';
import React from 'react';
const PokemonImage = ({ name }) => {
const { loading, cacheValue = {} } = useGraphQL({
fetchOptionsOverride(options) {
options.url = 'https://graphql-pokemon.now.sh';
},
operation: {
query: `{ pokemon(name: "${name}") { image } }`,
},
loadOnMount: true,
loadOnReload: true,
loadOnReset: true,
});
return cacheValue.data ? (
<img src={cacheValue.data.pokemon.image} alt={name} />
) : loading ? (
'Loading…'
) : (
'Error!'
);
};
Options guide for common situations.
Situation loadOnMount
loadOnReload
loadOnReset
reloadOnLoad
resetOnLoad
Profile query ✔️ ✔️ ✔️ Login mutation ✔️ Logout mutation ✔️ Change password mutation Change name mutation ✔️ Like a post mutation ✔️
React context object for a GraphQL
instance.
Type: object
Property | Type | Description |
---|---|---|
Provider | Function | React context provider component. |
Consumer | Function | React context consumer component. |
GraphQLProvider
is used to provide this context.useGraphQL
React hook requires an ancestor GraphQLContext
Provider
to work.Ways to import
.
import { GraphQLContext } from 'graphql-react';
import GraphQLContext from 'graphql-react/universal/GraphQLContext.js';
Ways to require
.
const { GraphQLContext } = require('graphql-react');
const GraphQLContext = require('graphql-react/universal/GraphQLContext');
A button component that resets the GraphQL cache.
import { GraphQLContext } from 'graphql-react';
import React from 'react';
const ResetCacheButton = () => {
const graphql = React.useContext(GraphQLContext);
return <button onClick={graphql.reset}>Reset cache</button>;
};
A GraphQL cache map of GraphQL operation results.
Type: object<GraphQLCacheKey, GraphQLCacheValue>
GraphQL
constructor accepts this type in options.cache
.GraphQL
instance property cache
is this type.A GraphQL cache key, derived from a hash of the fetch
options of the GraphQL operation that populated the value.
Type: string
JSON serializable GraphQL operation result that includes errors and data.
Type: object
Property | Type | Description |
---|---|---|
fetchError | string? | fetch error message. |
httpError | HttpError? | fetch response HTTP error. |
parseError | string? | Parse error message. |
graphQLErrors | Array<object>? | GraphQL response errors. |
data | object? | GraphQL response data. |
GraphQL API URL and polyfillable fetch
options. The url
property gets extracted and the rest are used as fetch
options.
Type: object
Property | Type | Description |
---|---|---|
url | string | GraphQL API URL. |
body | string | FormData | HTTP request body. |
headers | object | HTTP request headers. |
credentials | string? | Authentication credentials mode. |
GraphQLFetchOptionsOverride
functions accept this type.Overrides default GraphQL fetch
options. Mutate the provided options object; there is no need to return it.
Type: Function
Parameter | Type | Description |
---|---|---|
options | GraphQLFetchOptions | GraphQL fetch options tailored to the GraphQL operation, e.g. if there are files to upload options.body will be a FormData instance conforming to the GraphQL multipart request spec. |
GraphQL
instance method operate
accepts this type in options.fetchOptionsOverride
.useGraphQL
React hook accepts this type in options.fetchOptionsOverride
.Setting GraphQL fetch
options for an imaginary API.
(options) => {
options.url = 'https://api.example.com/graphql';
options.credentials = 'include';
};
A GraphQL operation. Additional properties may be used; all are sent to the GraphQL server.
Type: object
Property | Type | Description |
---|---|---|
query | string | GraphQL queries/mutations. |
variables | object | Variables used in the query . |
GraphQL
instance method operate
accepts this type in options.operation
.useGraphQL
React hook accepts this type in options.operation
.A loading GraphQL operation.
Type: object
Property | Type | Description |
---|---|---|
cacheKey | GraphQLCacheKey | GraphQL cache key. |
cacheValue | GraphQLCacheValue? | GraphQL cache value from the last identical query. |
cacheValuePromise | Promise<GraphQLCacheValue> | Resolves the loaded GraphQL cache value. |
GraphQL
instance method operate
returns this type.The status of a GraphQL operation.
Type: object
Property | Type | Description |
---|---|---|
load | Function | Loads the GraphQL operation on demand, updating the GraphQL cache. |
loading | boolean | Is the GraphQL operation loading. |
cacheKey | GraphQLCacheKey | GraphQL cache key. |
cacheValue | GraphQLCacheValue | GraphQL cache value. |
useGraphQL
React hook returns this type.fetch
HTTP error.
Type: object
Property | Type | Description |
---|---|---|
status | number | HTTP status code. |
statusText | string | HTTP status text. |
A React virtual DOM node; anything that can be rendered.
Type: undefined
| null
| boolean | number | string | React.Element | Array<ReactNode>
A < 3 KB bundle impact is guaranteed by Size Limit tests. The impact is smaller than the bundle size badge suggests as the internal object-assign
dependency is shared with react
.
Dependency | Install size | Bundle size |
---|---|---|
graphql-react |
The bundle impact may be smaller, depending on how much of the API you use.
Several dependencies must be installed for a minimal Apollo project.
Dependency | Install size | Bundle size |
---|---|---|
@apollo/client | ||
graphql |
Tree shaking bundlers will eliminate unused graphql
exports.
Consuming the API multiple ways in a project or it’s dependencies causes massive duplication in a bundle (doubling or tripling the bundle impact); see ESM.
In addition, possibleTypes
config impacts bundle size relative to the number and complexity of schema unions and interfaces; see Cache strategy.
Supports both CJS and ESM in Node.js whilst avoiding the dual package hazard and ensuring private internal code can’t be accessed from outside the package, via package.json
exports
field conditional exports.
Individual parts of the public API exist in separate CJS .js
files that can be accessed via:
graphql-react
specifier, while earlier versions and Rollup can only tree shake imports from graphql-react/universal/index.mjs
.Consuming the API multiple ways in a project or it’s dependencies doesn’t cause duplication in a bundle.
Faux ESM that can’t be used by Node.js (files don't have the .mjs
extension and import specifiers don't contain file extensions) is provided via a package module
field for tree shaking bundlers like webpack and Rollup.
Arbitrary CJS bundles are available at the main index and specific deep paths.
Consuming the API multiple ways in a project or it’s dependencies causes massive duplication in a bundle. This can easily double or triple the bundle impact.
Uses template strings:
const QUERY = /* GraphQL */ `
{
viewer {
id
}
}
`;
The optional /* GraphQL */
comment signals the syntax for highlighters and linters.
Uses template strings tagged with gql
, re-exported from graphql-tag
:
import { gql } from '@apollo/client';
const QUERY = gql`
{
viewer {
id
}
}
`;
This complexity impacts bundle size and runtime performance. babel-plugin-graphql-tag
can be used to process the queries at build time, but this replaces the original strings with larger objects.
The GraphQL
client has no GraphQL API specific config; fetch
options are determined on demand at the component level. Multiple GraphQL APIs can be queried!
GraphQL operations are cached under hashes of their fetch
options. Multiple operations with the same hash share the same loading status and cache value.
fetch
, HTTP, parse and GraphQL errors can be cached, and therefore server side rendered and transported to the client for hydration and initial render.
Apollo Client is configured for one GraphQL API per app.
GraphQL operation data is deconstructed based upon id
and __typename
fields into a “normalized” cache. These fields must be queried even if they aren’t used in components.
Errors aren’t cached, and therefore can’t be server side rendered and transported to the client for hydration and initial render.
To cache fragments on unions and interfaces properly, Apollo Client must be configured with schema knowledge extracted at build time, via possibleTypes
. It’s challenging to reconfigure and redeploy clients whenever the GraphQL schema updates. Also, the config increases the client bundle size; see Bundle impact.
Typically, cache is refreshed for mounting components.
GraphQL operations can optionally refresh all cache except their own fresh cache; handy for mutations.
Typically, cache isn’t refreshed for mounting components.
GraphQL mutations only update the cache with the contents of their payload. The prescribed approach is to try to manually update other normalized cache after mutations using complicated and often buggy APIs. Resetting all cache is possible, but it also wipes the result of the last operation.
Supports file uploads out of the box, compliant with the GraphQL multipart request spec (authored by @jaydenseric) which is supported by popular GraphQL servers including Apollo Server. File input values and more can be used as query or mutation arguments.
Supports file uploads if you manually setup Apollo Client with apollo-upload-client
(also by @jaydenseric).
Not supported yet, see #15.
Supported.
Written in ECMAScript; no types are exported. Type definitions are available via @types/graphql-react
.
Written in TypeScript; types are exported.
Has an official example using next-graphql-react
, which is an easily installed integration to enable server side rendered GraphQL queries.
Also has more detailed examples, deployed at graphql-react.now.sh.
Has an official example with boilerplate code to manually copy. It’s difficult to stay up to date with the frequent changes.
11.0.4
import
and require
the package exports.FAQs
A GraphQL client for React using modern context and hooks APIs that’s lightweight (< 4 kB) but powerful; the first Relay and Apollo alternative with server side rendering.
The npm package graphql-react receives a total of 1,669 weekly downloads. As such, graphql-react popularity was classified as popular.
We found that graphql-react demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.