Skip to content

Instantly share code, notes, and snippets.

@hanpama
Last active December 17, 2018 14:53
Show Gist options
  • Save hanpama/47b9431af1a981c32c7ce6e353ff800b to your computer and use it in GitHub Desktop.
Save hanpama/47b9431af1a981c32c7ce6e353ff800b to your computer and use it in GitHub Desktop.
NodeJS http client implementation of GraphQL multipart request
import * as http from 'http';
import FormData from 'form-data';
export class MultipartClient {
constructor(public requestOptions: { host: string, port: number } | { socketPath: string }) {}
async request(method: string, path: string, body?: any, headers: any = {}) {
return new Promise<{ res: http.IncomingMessage, body: Buffer }>((resolve, reject) => {
const req = http.request({
...this.requestOptions,
method,
headers,
path,
});
req.once('error', reject);
req.once('response', async (res: http.IncomingMessage) => {
const bufs: Buffer[] = [];
res.on('data', buf => { bufs.push(buf); });
res.on('end', () => resolve({ res, body: Buffer.concat(bufs) }));
});
if (!body) {
req.end();
}
else if (typeof body.pipe === 'function') {
body.pipe(req);
body.once('finish', () => req.end());
} else {
req.write(body);
req.end();
}
});
}
async sendQuery(data: { query: string, variables?: any }, headers: any = {}) {
const { body } = await this.request('POST', '/graphql', JSON.stringify(data), {
'Content-Type': 'application/json',
...headers,
});
return JSON.parse(body.toString());
}
async sendQueryWithFiles(data: { query: string, map: any, variables: any, files?: Readable[] }, headers: any = {}) {
const form = new FormData();
const { query, map, variables, files } = data;
form.append('operations', JSON.stringify({ query, variables }));
form.append('map', JSON.stringify(map));
if (files) {
files.forEach((file, idx) => {
form.append(String(idx), file);
});
}
const { body } = await this.request('POST', '/graphql', form, {
...form.getHeaders(),
...headers,
});
return JSON.parse(body.toString());
}
}
const res = await client.sendQueryWithFiles({
query: `
mutation($upload: Upload!) {
echoFileContent(upload: $upload)
}
`,
map: { 0: ['variables.upload'] },
variables: {
upload: null,
},
files: [
createReadStream('./LICENSE'),
],
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment