Skip to content

About

A terminating Apollo Link for Apollo Client that handles GraphQL file uploads using multipart requests.

Topics

Resources

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@hyperse/apollo-upload-client

A terminating Apollo Link for Apollo Client that handles GraphQL file uploads using multipart requests. When GraphQL variables contain files (FileList, File, or Blob instances), it sends a multipart/form-data request. Otherwise, it falls back to standard GraphQL POST/GET requests based on the configuration and operation type.

Build Version Top Language License

Features

  • πŸš€ Seamless Integration: Drop-in replacement for Apollo Client's HttpLink
  • πŸ“ File Upload Support: Handles File, Blob, and FileList instances automatically
  • πŸ”„ Smart Request Handling: Automatically switches between multipart and regular GraphQL requests
  • 🎯 TypeScript Support: Full TypeScript support with comprehensive type definitions
  • 🌐 Universal Compatibility: Works in browsers, React Native, and Node.js environments
  • ⚑ Performance Optimized: Efficient file extraction and request handling

Installation

npm install @hyperse/apollo-upload-client
# or
yarn add @hyperse/apollo-upload-client
# or
pnpm add @hyperse/apollo-upload-client

Quick Start

Basic Setup

import { ApolloClient, InMemoryCache, ApolloLink } from '@apollo/client';
import { UploadHttpLink } from '@hyperse/apollo-upload-client';

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: ApolloLink.from([
    new UploadHttpLink({
      uri: '/graphql',
    }),
  ]),
});

With Multiple Links

import { ApolloClient, InMemoryCache, ApolloLink } from '@apollo/client';
import { UploadHttpLink } from '@hyperse/apollo-upload-client';

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: ApolloLink.from([
    new ClientAwarenessLink(),
    // Add other links here (e.g., error handling, authentication)
    new UploadHttpLink({
      uri: '/graphql',
    }),
  ]),
});

Usage

File Upload Mutation

import { gql, useMutation } from '@apollo/client';

const UPLOAD_FILE = gql`
  mutation UploadFile($file: Upload!, $description: String) {
    uploadFile(file: $file, description: $description) {
      id
      filename
      url
    }
  }
`;

function FileUploadComponent() {
  const [uploadFile, { loading, error, data }] = useMutation(UPLOAD_FILE);

  const handleFileChange = (event) => {
    const file = event.target.files[0];
    if (file) {
      uploadFile({
        variables: {
          file: file,
          description: 'My uploaded file'
        }
      });
    }
  };

  return (
    <div>
      <input type="file" onChange={handleFileChange} />
      {loading && <p>Uploading...</p>}
      {error && <p>Error: {error.message}</p>}
      {data && <p>File uploaded: {data.uploadFile.filename}</p>}
    </div>
  );
}

Multiple File Upload

const UPLOAD_MULTIPLE_FILES = gql`
  mutation UploadMultipleFiles($files: [Upload!]!) {
    uploadMultipleFiles(files: $files) {
      id
      filename
      url
    }
  }
`;

function MultipleFileUploadComponent() {
  const [uploadFiles, { loading }] = useMutation(UPLOAD_MULTIPLE_FILES);

  const handleFilesChange = (event) => {
    const files = Array.from(event.target.files);
    if (files.length > 0) {
      uploadFiles({
        variables: {
          files: files
        }
      });
    }
  };

  return (
    <input type="file" multiple onChange={handleFilesChange} />
  );
}

API Reference

UploadHttpLink

The main class that handles file uploads in GraphQL requests.

Constructor Options

interface UploadHttpLinkOptions<T extends ExtractableFile> {
  // HTTP Link options
  uri?: string;
  fetch?: WindowOrWorkerGlobalScope['fetch'];
  headers?: Record<string, string>;
  credentials?: RequestCredentials;

  // Upload-specific options
  FormData?: typeof FormData;
  isExtractableFile?: ExtractableFileMatcher<T>;
  formDataAppendFile?: FormDataFileAppender<T>;
}

Options

  • uri (string, default: /graphql): The GraphQL endpoint URI
  • fetch (function): Custom fetch implementation
  • headers (object): Additional HTTP headers
  • credentials (string): Request credentials policy
  • FormData (class): Custom FormData implementation
  • isExtractableFile (function): Custom file detection logic
  • formDataAppendFile (function): Custom file appending logic

ExtractableFile

type ExtractableFile = File | Blob;

Supported file types that can be automatically detected and uploaded.

extractFiles

Utility function to extract files from objects and create upload-ready data.

import {
  extractFiles,
  isExtractableFile,
} from '@hyperse/apollo-upload-client/extractFiles';

const { clone, files } = extractFiles(
  { file: myFile, data: { nested: { file: anotherFile } } },
  isExtractableFile
);

How It Works

  1. Request Analysis: The link analyzes GraphQL operation variables for file objects
  2. Smart Routing:
    • If files are detected: Creates a multipart/form-data request
    • If no files: Falls back to regular GraphQL HTTP request
  3. File Extraction: Extracts files and their object paths from variables
  4. Request Construction: Builds the multipart request according to the GraphQL multipart request specification
  5. Response Handling: Processes the response and forwards it to Apollo Client

License

MIT License - see LICENSE file for details.

Support

Related Projects


Made with ❀️ by the Hyperse team

About

A terminating Apollo Link for Apollo Client that handles GraphQL file uploads using multipart requests.

Topics

Resources

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages