Data Fetching in EverShop
EverShop uses GraphQL for data fetching. GraphQL is a query language for your API and a server-side runtime for executing queries using a type system you define for your data.
Check this GraphQL document to learn more about GraphQL in EverShop.
EverShop allows you to fetch data for your React components using the GraphQL query language. This document explains how to fetch data from the server using GraphQL.
GraphQL Query in React Components
When creating a React component that requires data for SSR (Server-Side Rendering), you need to fetch the data from the server during the request time. To do this, export a GraphQL query in the React component file. The query will be executed on the server, and the result will be passed to the React component as a prop.
Let's look at the example below:
export default function GeneralInfo({ product }) {
return (
<Area
id="productViewGeneralInfo"
coreComponents={[
{
component: { default: Name },
props: {
name: product.name,
},
sortOrder: 10,
id: "productSingleName",
},
{
component: { default: Price },
props: {
regular: product.price.regular,
special: product.price.special,
},
sortOrder: 10,
id: "productSinglePrice",
},
{
component: { default: Sku },
props: {
sku: product.sku,
},
sortOrder: 20,
id: "productSingleSku",
},
]}
/>
);
}
export const query = `
query Query {
product (id: getContextValue('productId')) {
name
sku
price {
regular {
value
text
}
special {
value
text
}
}
}
}`;
In the example above, we export a GraphQL query in the GeneralInformation.js
component file. During the request time, EverShop consolidates all queries from all components and executes them in a single request. The result of the GraphQL query is passed to the React component as a prop.
When is the GraphQL Query Executed?
The query is executed on the server during the request time. It will only be executed if the component is rendered on the server.
The GraphQL query is extracted from the component file and executed on the server. The result of the query is then passed to the component as a prop.
The GraphQL Query Format
Since the build process uses Regex to parse, collect, and remove queries from the component file, you must ensure the export statement follows the format below:
export const query = `<Your GraphQL query>`;
The getContextValue
Function
Sometimes, you need to pass arguments to the GraphQL query. For example, to fetch product details for a specific product, you need to pass the product ID to the GraphQL query. To do this, use the getContextValue
function. This function returns the value of the context key you pass to it.
export const query = `
query Query {
product (id: getContextValue('productId')) {
name
sku
price {
regular {
value
text
}
special {
value
text
}
}
}
}`;
To add a value to the context, use a middleware function. Here's an example:
import { select } from "@evershop/postgres-query-builder";
import { pool } from "@evershop/evershop/lib/postgres";
import { setContextValue } from "@evershop/evershop/graphql/services";
export default async (request, response, next) => {
try {
const query = select();
query
.from("category")
.leftJoin("category_description")
.on(
"category.`category_id`",
"=",
"category_description.`category_description_category_id`"
);
query.where("category_description.`url_key`", "=", request.params.url_key);
const category = await query.load(pool);
if (category === null) {
response.status(404);
next();
} else {
setContextValue(request, "categoryId", category.category_id);
setContextValue(request, "pageInfo", {
title: category.meta_title || category.name,
description: category.meta_description || category.short_description,
url: request.url,
});
next();
}
} catch (e) {
next(e);
}
};
In the example above, the middleware function index.js
validates the category's availability. If the category is available, we add the category ID to the context using the setContextValue
function. The getContextValue
function then retrieves the category ID from the context.
The setContextValue
Function
This function adds a value to the GraphQL execution context. It accepts three arguments:
request
: The request object.key
: The context key.value
: The context value.
By default, EverShop adds all data in the current request
object to the context. For example, you can call the getContextValue('url')
function to get the current request URL.
Client-Side Data Fetching
GraphQL API Endpoint
EverShop provides a GraphQL API endpoint to fetch data from the server. The GraphQL API endpoint is available at the /graphql
path. You can use this endpoint to fetch data from the server.
The useQuery
Hook from URQL
EverShop uses URQL to fetch data from the server using the GraphQL API. URQL is a fully-featured GraphQL client that supports all GraphQL features and can be used with any GraphQL server.
Example:
import React from "react";
import { useQuery } from "urql";
const TodosQuery = `
query {
todos {
id
title
}
}
`;
const Todos = () => {
const [result, reexecuteQuery] = useQuery({
query: TodosQuery,
});
const { data, fetching, error } = result;
if (fetching) return <p>Loading...</p>;
if (error) return <p>Oh no... {error.message}</p>;
return (
<ul>
{data.todos.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
};
Support us
EverShop is an open-source project that relies on community support. If you find our project useful, please consider sponsoring us.