UNPKG

15.4 kBMarkdownView Raw
1# GraphQL Client
2
3The GraphQL Client can be used to interact with any Shopify's GraphQL APIs. Client users are expected to provide the full API URL and necessary headers.
4
5
6## Getting Started
7Using your preferred package manager, install this package in a project:
8
9```sh
10yarn add @shopify/graphql-client
11```
12
13```sh
14npm install @shopify/graphql-client --s
15```
16
17```sh
18pnpm add @shopify/graphql-client
19```
20
21### CDN
22The UMD builds of each release version are available via the [`unpkg` CDN](https://unpkg.com/browse/@shopify/graphql-client@latest/dist/umd/)
23
24```html
25// The minified `v0.9.3` version of the GraphQL API Client
26<script src="https://unpkg.com/@shopify/graphql-client@0.9.3/dist/umd/graphql-client.min.js"></script>
27
28<script>
29const client = ShopifyGraphQLClient.createGraphQLClient({...});
30</script>
31```
32
33## Client initialization
34
35```typescript
36import {createGraphQLClient} from '@shopify/graphql-client';
37
38const client = createGraphQLClient({
39 url: 'http://your-shop-name.myshopify.com/api/2023-10/graphql.json',
40 headers: {
41 'Content-Type': 'application/json',
42 'X-Shopify-Storefront-Access-Token': 'public-token',
43 },
44 retries: 1
45});
46```
47
48### Create a server enabled client using a custom Fetch API
49
50In order to use the client within a server, a server enabled JS Fetch API will need to be provided to the client at initialization. By default, the client uses `window.fetch` for network requests.
51
52```typescript
53import {createGraphQLClient} from '@shopify/graphql-client';
54import {fetch as nodeFetch} from 'node-fetch';
55
56const client = createGraphQLClient({
57 url: 'http://your-shop-name.myshopify.com/api/2023-10/graphql.json',
58 headers: {
59 'Content-Type': 'application/json',
60 'X-Shopify-Storefront-Access-Token': 'public-token',
61 },
62 customFetchApi: nodeFetch
63});
64```
65
66### `createGraphQLClient()` parameters
67
68| Property | Type | Description |
69| -------- | ------------------------ | ---------------------------------- |
70| url | `string` | The GraphQL API URL |
71| headers | `Record<string, string \| string[]>` | Headers to be included in requests |
72| retries? | `number` | The number of HTTP request retries if the request was abandoned or the server responded with a `Too Many Requests (429)` or `Service Unavailable (503)` response. Default value is `0`. Maximum value is `3`. |
73| customFetchApi? | `(url: string, init?: {method?: string, headers?: HeaderInit, body?: string}) => Promise<Response>` | A replacement `fetch` function that will be used in all client network requests. By default, the client uses `window.fetch()`. |
74| logger? | `(logContent: `[`HTTPResponseLog`](#httpresponselog)`\|`[`HTTPRetryLog`](#httpretrylog)`) => void` | A logger function that accepts [log content objects](#log-content-types). This logger will be called in certain conditions with contextual information. |
75
76## Client properties
77
78| Property | Type | Description |
79| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
80| config | `{url: string, headers: Record<string, string \| string[]>, retries: number}` | Configuration for the client |
81| fetch | `(operation: string, options?: `[`RequestOptions`](#requestoptions-properties)`) => Promise<Response>` | Fetches data from the GraphQL API using the provided GQL operation string and [`RequestOptions`](#requestoptions-properties) object and returns the network response |
82| request | `<TData>(operation: string, options?: `[`RequestOptions`](#requestoptions-properties)`) => Promise<`[`ClientResponse<TData>`](#ClientResponsetdata)`>` | Fetches data from the GraphQL API using the provided GQL operation string and [`RequestOptions`](#requestoptions-properties) object and returns a [normalized response object](#clientresponsetdata) |
83| requestStream | `<TData>(operation: string, options?: `[`RequestOptions`](#requestoptions-properties)`) => Promise <AsyncIterator<`[`ClientStreamResponse<TData>`](#clientstreamresponsetdata)`>>` | Fetches GQL operations that can result in a streamed response from the API (eg. [Storefront API's `@defer` directive](https://shopify.dev/docs/api/storefront#directives)). The function returns an async iterator and the iterator will return [normalized stream response objects](#clientstreamresponsetdata) as data becomes available through the stream. |
84
85## `RequestOptions` properties
86
87| Name | Type | Description |
88| ---------- | --------------------- | ---------------------------------------------------------------- |
89| variables? | `Record<string, any>` | Variable values needed in the graphQL operation |
90| url? | `string` | Alternative request API URL |
91| headers? | `Record<string, string \| string[]>` | Additional and/or replacement headers to be used in the request |
92| retries? | `number` | Alternative number of retries for the request. Retries only occur for requests that were abandoned or if the server responds with a `Too Many Request (429)` or `Service Unavailable (503)` response. Minimum value is `0` and maximum value is `3`.|
93
94## `ClientResponse<TData>`
95
96| Name | Type | Description |
97| ----------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98| data? | `TData \| any` | Data returned from the GraphQL API. If `TData` was provided to the function, the return type is `TData`, else it returns type `any`. |
99| errors? | [`ResponseErrors`](#responseerrors) | Errors object that contains any API or network errors that occured while fetching the data from the API. It does not include any `UserErrors`. |
100| extensions? | `Record<string, any>` | Additional information on the GraphQL response data and context. It can include the `context` object that contains the context settings used to generate the returned API response. |
101
102## `ClientStreamResponse<TData>`
103
104| Name | Type | Description |
105| ----------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
106| data? | `TData \| any` | Currently available data returned from the GraphQL API. If `TData` was provided to the function, the return type is `TData`, else it returns type `any`. |
107| errors? | [`ResponseErrors`](#responseerrors) | Errors object that contains any API or network errors that occured while fetching the data from the API. It does not include any `UserErrors`. |
108| extensions? | `Record<string, any>` | Additional information on the GraphQL response data and context. It can include the `context` object that contains the context settings used to generate the returned API response. |
109| hasNext | `boolean` | Flag to indicate whether the response stream has more incoming data |
110
111## `ResponseErrors`
112
113| Name | Type | Description |
114| ----------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115| networkStatusCode? | `number` | HTTP response status code |
116| message? | `string` | The provided error message |
117| graphQLErrors? | `any[]` | The GraphQL API errors returned by the server |
118| response? | `Response` | The raw response object from the network fetch call |
119
120## Usage examples
121
122### Query for a product
123
124```typescript
125const productQuery = `
126 query ProductQuery($handle: String) {
127 product(handle: $handle) {
128 id
129 title
130 handle
131 }
132 }
133`;
134
135const {data, errors, extensions} = await client.request(productQuery, {
136 variables: {
137 handle: 'sample-product',
138 },
139});
140```
141
142### Query for product info using the `@defer` directive
143
144```typescript
145const productQuery = `
146 query ProductQuery($handle: String) {
147 product(handle: $handle) {
148 id
149 handle
150 ... @defer(label: "deferredFields") {
151 title
152 description
153 }
154 }
155 }
156`;
157
158const responseStream = await client.requestStream(productQuery, {
159 variables: {handle: 'sample-product'},
160});
161
162// await available data from the async iterator
163for await (const response of responseStream) {
164 const {data, errors, extensions, hasNext} = response;
165}
166```
167
168### Add additional custom headers to the API request
169
170```typescript
171const productQuery = `
172 query ProductQuery($handle: String) {
173 product(handle: $handle) {
174 id
175 title
176 handle
177 }
178 }
179`;
180
181const {data, errors, extensions} = await client.request(productQuery, {
182 variables: {
183 handle: 'sample-product',
184 },
185 headers: {
186 'Shopify-Storefront-Id': 'shop-id',
187 },
188});
189```
190
191### Use an updated API URL in the API request
192
193```typescript
194const productQuery = `
195 query ProductQuery($handle: String) {
196 product(handle: $handle) {
197 id
198 title
199 handle
200 }
201 }
202`;
203
204const {data, errors, extensions} = await client.request(productQuery, {
205 variables: {
206 handle: 'sample-product',
207 },
208 url: 'http://your-shop-name.myshopify.com/api/unstable/graphql.json',
209});
210```
211
212### Set a custom retries value in the API request
213
214```typescript
215const shopQuery = `
216 query ShopQuery {
217 shop {
218 name
219 id
220 }
221 }
222`;
223
224// Will retry the HTTP request to the server 2 times if the requests were abandoned or the server responded with a 429 or 503 error
225const {data, errors, extensions} = await client.request(shopQuery, {
226 retries: 2,
227});
228```
229
230### Provide GQL query type to `client.request()` and `client.requestStream()`
231
232```typescript
233import {print} from 'graphql/language';
234
235// GQL operation types are usually auto generated during the application build
236import {CollectionQuery, CollectionDeferredQuery} from 'types/appTypes';
237import collectionQuery from './collectionQuery.graphql';
238import collectionDeferredQuery from './collectionDeferredQuery.graphql';
239
240const {data, errors, extensions} = await client.request<CollectionQuery>(
241 print(collectionQuery),
242 {
243 variables: {
244 handle: 'sample-collection',
245 },
246 }
247);
248
249const responseStream = await client.requestStream<CollectionDeferredQuery>(
250 print(collectionDeferredQuery),
251 {
252 variables: {handle: 'sample-collection'},
253 }
254);
255```
256
257### Using `client.fetch()` to get API data
258
259```typescript
260const shopQuery = `
261 query shop {
262 shop {
263 name
264 id
265 }
266 }
267`;
268
269const response = await client.fetch(shopQuery);
270
271if (response.ok) {
272 const {errors, data, extensions} = await response.json();
273}
274```
275
276## Log Content Types
277
278### `HTTPResponseLog`
279
280This log content is sent to the logger whenever a HTTP response is received by the client.
281
282| Property | Type | Description |
283| -------- | ------------------------ | ---------------------------------- |
284| type | `LogType['HTTP-Response']` | The type of log content. Is always set to `HTTP-Response` |
285| content | `{`[`requestParams`](#requestparams)`: [url, init?], response: Response}` | Contextual data regarding the request and received response |
286
287### `HTTPRetryLog`
288
289This log content is sent to the logger whenever the client attempts to retry HTTP requests.
290
291| Property | Type | Description |
292| -------- | ------------------------ | ---------------------------------- |
293| type | `LogType['HTTP-Retry']` | The type of log content. Is always set to `HTTP-Retry` |
294| content | `{`[`requestParams`](#requestparams)`: [url, init?], lastResponse?: Response, retryAttempt: number, maxRetries: number}` | Contextual data regarding the upcoming retry attempt. <br /><br/>`requestParams`: [parameters](#requestparams) used in the request<br/>`lastResponse`: previous response <br/> `retryAttempt`: the current retry attempt count <br/> `maxRetries`: the maximum number of retries |
295
296### `RequestParams`
297
298| Property | Type | Description |
299| -------- | ------------------------ | ---------------------------------- |
300| url | `string` | Requested URL |
301| init? | `{method?: string, headers?: HeaderInit, body?: string}` | The request information |