1634194800
This is the seventh instalment of our full-stack GraphQL + React tutorial, which walks you through building a messaging app. Each section is self-contained and focuses on a few new subjects, so you may start where you choose or go through the entire series…
1623293670
GraphQL subscriptions are based on a simple publish-subscribe system. In our server-side subscriptions package, when a client makes a subscription, we simply use a map from one subscription name to one or more channel names to subscribe to the right channels. The subscription query will be re-run every time something is published to one of these channels. We think a common pattern will be to publish mutation results to a channel, so a subscription can send a new result to clients whenever a mutation happens. This is why some people call subscriptions the result of someone else’s mutation .
#apollo client #subscriptions #graphql
1622282384
A real-world example
At Scaphold, we manage a lot of infrastructure to make sure our customers’ APIs stay available and performant. One of our core features is a graphical schema designer that allows you to easily define the GraphQL schema that will come to define your Scaphold API. What you don’t see when playing around with our schema designer, however, is a complex migration system that makes sure your API’s database is always up to date and in adherence with your schema. When you make a migration to your schema, the machine that fields the migration request will make the necessary changes to your database so that your API stays in sync.
#graphql #graphql subscriptions #apollo
1622720280
Apollo client is a powerful frontend GraphQL library that allows an application using GraphQL to query itself, and the connected GraphQL data service. It is a client side state management library that integrates deeply with GraphQL backends.
Under the covers, Apollo client takes your GraphQL query response, and flattens it into a key-value storage system. Take the following example:
// GraphQL Query and Type
type Account {
id: ID!
userName: String!
}
query getAccount() {
account {
id
userName
__typename // not required, but for illustration
}
}
The query above for a value on type Account, would return a response like this:
{
data: {
account: {
id: 1,
userName: 'user',
__typename: 'Account'
}
}
}
#apollo #graphql #apollo-client #javascript #react
1616571282
The ever changing world of front end development continues to evolve and introduce many different libraries to solve your problems. As GraphQL continues to grow in popularity, the tools and libraries surrounding it change also. Recently I helped write a new application that interacted solely with a GraphQL backend, and used Apollo Client (AC) to interact with instead of Redux in our React frontend application. Having previously written many javascript apps with Redux, here are some takeaways from my experience.
Disclaimer: Comparing the two libraries assumes you are working with a GraphQL backend. Apollo Client doesn’t work with other types of backends and isn’t a viable alternative to Redux in that case.
#graphql #redux #apollo-client #javascript #apollo
1639797442
A terminating Apollo Link for Apollo Client that fetches a GraphQL multipart request if the GraphQL variables contain files (by default FileList
, File
, Blob
, or ReactNativeFile
instances), or else fetches a regular GraphQL POST or GET request (depending on the config and GraphQL operation).
To install with npm, run:
npm install apollo-upload-client
Remove any uri
, credentials
, or headers
options from the ApolloClient
constructor.
Apollo Client can only have 1 terminating Apollo Link that sends the GraphQL requests; if one such as HttpLink
is already setup, remove it.
Initialize the client with a terminating Apollo Link using createUploadLink
.
Also ensure the GraphQL server implements the GraphQL multipart request spec and that uploads are handled correctly in resolvers.
Use FileList
, File
, Blob
or ReactNativeFile
instances anywhere within query or mutation variables to send a GraphQL multipart request.
See also the example API and client.
FileList
import { gql, useMutation } from "@apollo/client";
const MUTATION = gql`
mutation ($files: [Upload!]!) {
uploadFiles(files: $files) {
success
}
}
`;
function UploadFiles() {
const [mutate] = useMutation(MUTATION);
function onChange({ target: { validity, files } }) {
if (validity.valid) mutate({ variables: { files } });
}
return <input type="file" multiple required onChange={onChange} />;
}
File
import { gql, useMutation } from "@apollo/client";
const MUTATION = gql`
mutation ($file: Upload!) {
uploadFile(file: $file) {
success
}
}
`;
function UploadFile() {
const [mutate] = useMutation(MUTATION);
function onChange({
target: {
validity,
files: [file],
},
}) {
if (validity.valid) mutate({ variables: { file } });
}
return <input type="file" required onChange={onChange} />;
}
Blob
import { gql, useMutation } from "@apollo/client";
const MUTATION = gql`
mutation ($file: Upload!) {
uploadFile(file: $file) {
success
}
}
`;
function UploadFile() {
const [mutate] = useMutation(MUTATION);
function onChange({ target: { validity, value } }) {
if (validity.valid) {
const file = new Blob([value], { type: "text/plain" });
// Optional, defaults to `blob`.
file.name = "text.txt";
mutate({ variables: { file } });
}
}
return <input type="text" required onChange={onChange} />;
}
^12.22.0 || ^14.17.0 || >= 16.0.0
> 0.5%, not OperaMini all, not IE > 0, not dead
Consider polyfilling:
Used to mark React Native File
substitutes as it’s too risky to assume all objects with uri
, type
and name
properties are extractable files.
Parameter | Type | Description |
---|---|---|
file | ReactNativeFileSubstitute | A React Native File substitute. |
Ways to import
.
import { ReactNativeFile } from "apollo-upload-client";
import ReactNativeFile from "apollo-upload-client/public/ReactNativeFile.js";
Ways to require
.
const { ReactNativeFile } = require("apollo-upload-client");
const ReactNativeFile = require("apollo-upload-client/public/ReactNativeFile.js");
A file in React Native that can be used in query or mutation variables.
const file = new ReactNativeFile({ uri: uriFromCameraRoll, name: "a.jpg", type: "image/jpeg", });
Creates a terminating Apollo Link for Apollo Client that fetches a GraphQL multipart request if the GraphQL variables contain files (by default FileList
, File
, Blob
, or ReactNativeFile
instances), or else fetches a regular GraphQL POST or GET request (depending on the config and GraphQL operation).
Some of the options are similar to the createHttpLink
options.
Parameter | Type | Description |
---|---|---|
options | object | Options. |
options.uri | string? = /graphql | GraphQL endpoint URI. |
options.useGETForQueries | boolean? | Should GET be used to fetch queries, if there are no files to upload. |
options.isExtractableFile | ExtractableFileMatcher? = isExtractableFile | Customizes how files are matched in the GraphQL operation for extraction. |
options.FormData | class? | FormData implementation to use, defaulting to the FormData global. |
options.formDataAppendFile | FormDataFileAppender? = formDataAppendFile | Customizes how extracted files are appended to the FormData instance. |
options.fetch | Function? | fetch implementation to use, defaulting to the fetch global. |
options.fetchOptions | FetchOptions? | fetch options; overridden by upload requirements. |
options.credentials | string? | Overrides options.fetchOptions.credentials . |
options.headers | object? | Merges with and overrides options.fetchOptions.headers . |
options.includeExtensions | boolean? = false | Toggles sending extensions fields to the GraphQL server. |
Returns: ApolloLink — A terminating Apollo Link.
Ways to import
.
import { createUploadLink } from "apollo-upload-client";
import createUploadLink from "apollo-upload-client/public/createUploadLink.js";
Ways to require
.
const { createUploadLink } = require("apollo-upload-client");
const createUploadLink = require("apollo-upload-client/public/createUploadLink.js");
A basic Apollo Client setup.
import { ApolloClient, InMemoryCache } from "@apollo/client"; import createUploadLink from "apollo-upload-client/public/createUploadLink.js"; const client = new ApolloClient({ cache: new InMemoryCache(), link: createUploadLink(), });
The default implementation for createUploadLink
options.formDataAppendFile
that uses the standard FormData.append
method.
Type: FormDataFileAppender
Parameter | Type | Description |
---|---|---|
formData | FormData | FormData instance to append the specified file to. |
fieldName | string | Field name for the file. |
file | * | File to append. |
Ways to import
.
import { formDataAppendFile } from "apollo-upload-client";
import formDataAppendFile from "apollo-upload-client/public/formDataAppendFile.js";
Ways to require
.
const { formDataAppendFile } = require("apollo-upload-client");
const formDataAppendFile = require("apollo-upload-client/public/formDataAppendFile.js");
The default implementation for createUploadLink
options.isExtractableFile
.
Type: ExtractableFileMatcher
Parameter | Type | Description |
---|---|---|
value | * | Value to check. |
Returns: boolean — Is the value an extractable file.
Ways to import
.
import { isExtractableFile } from "apollo-upload-client";
import isExtractableFile from "apollo-upload-client/public/isExtractableFile.js";
Ways to require
.
const { isExtractableFile } = require("apollo-upload-client");
const isExtractableFile = require("apollo-upload-client/public/isExtractableFile.js");
A function that checks if a value is an extractable file.
Type: Function
Parameter | Type | Description |
---|---|---|
value | * | Value to check. |
Returns: boolean — Is the value an extractable file.
isExtractableFile
has this type.How to check for the default exactable files, as well as a custom type of file.
import isExtractableFile from "apollo-upload-client/public/isExtractableFile.js"; const isExtractableFileEnhanced = (value) => isExtractableFile(value) || (typeof CustomFile !== "undefined" && value instanceof CustomFile);
GraphQL request fetch
options.
Type: object
Property | Type | Description |
---|---|---|
headers | object | HTTP request headers. |
credentials | string? | Authentication credentials mode. |
Appends a file extracted from the GraphQL operation to the FormData
instance used as the fetch
options.body
for the GraphQL multipart request.
Parameter | Type | Description |
---|---|---|
formData | FormData | FormData instance to append the specified file to. |
fieldName | string | Field name for the file. |
file | * | File to append. The file type depends on what the ExtractableFileMatcher extracts. |
formDataAppendFile
has this type.createUploadLink
accepts this type in options.formDataAppendFile
.A React Native File
substitute.
Be aware that inspecting network traffic with buggy versions of dev tools such as Flipper can interfere with the React Native FormData
implementation, causing multipart requests to have network errors.
Type: object
Property | Type | Description |
---|---|---|
uri | string | Filesystem path. |
name | string? | File name. |
type | string? | File content type. Some environments (particularly Android) require a valid MIME type; Expo ImageResult.type is unreliable as it can be just image . |
A camera roll file.
const fileSubstitute = { uri: uriFromCameraRoll, name: "a.jpg", type: "image/jpeg", };
Download Details:
Author: jaydenseric
Source Code: https://github.com/jaydenseric/apollo-upload-client
License: MIT
#apollo #graphql