Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A couple typos in new client plugins doc #874

Merged
merged 1 commit into from
Feb 1, 2023

Conversation

rmarscher
Copy link
Contributor

I noticed these while following the 1.0 migration docs and migrating our custom client fetch to a network plugin. Thanks!

@changeset-bot
Copy link

changeset-bot bot commented Feb 1, 2023

⚠️ No Changeset found

Latest commit: dbe1a8e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Feb 1, 2023

@rmarscher is attempting to deploy a commit to the HoudiniGraphQL Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
Copy link

vercel bot commented Feb 1, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated
docs ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Feb 1, 2023 at 5:23PM (UTC)
docs-next ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Feb 1, 2023 at 5:23PM (UTC)

@AlecAivazis
Copy link
Collaborator

oh nice! thanks for fixing those 👍

@AlecAivazis
Copy link
Collaborator

AlecAivazis commented Feb 1, 2023

Im curious to hear more about your experience with the client plugins! As far as I know, you're the first to write one that isn't me so any feedback on docs, mental model, etc would be huge 🙌

@rmarscher
Copy link
Contributor Author

I love the client plugins. The model makes sense to me. I like the composability options and it was pretty simple to port what we were doing pre-1.0 to a client plugin. We're using it for two things now:

  1. Do some additional data marshaling between our typescript objects and our graphql schema - we have some generated fields and some fields that we automatically encode/decode to JSON to workaround graphql's inability to store data with arbitrary keys.
  2. In server-side code that doesn't have a current user session -- like webhook handlers -- we prepare a custom fetch function that signs requests with IAM credentials (we use AWS AppSync as our graphql server and it supports IAM auth via these signed requests). We have a special IAM user that we treat as our "system" user for accessing the GraphGL API. We pass that custom fetch function down through the houdini metadata and in our network plugin, if it sees metadata.fetch is set, then it calls that instead of the default ctx.fetch.

Here's the network plugin:

async network(ctx, { resolve }) {
	let result: Response;
	// Ability for server-side queries to pass an alternate fetch
	if (ctx.metadata?.['fetch']) {
		const _fetch = ctx.metadata['fetch'] as typeof fetch;
		result = await _fetch(ctx.text, ctx.variables);
	} else {
		const options: RequestInit = {
			method: 'POST',
			credentials: 'include',
			headers: {
				'Content-Type': 'application/json',
			},
			body: JSON.stringify({
				query: ctx.text,
				variables: ctx.variables,
			}),
		};
		result = await ctx.fetch('/graphql', options);
	}
	const clonedResult = result.clone();
	try {
		resolve(ctx, await result.json());
	} catch (e) {
		console.log('Problem parsing result json: ', await clonedResult.text());
		throw e;
	}
},

And here's the custom fetch which we import in *.server.ts files and pass in our houdini fetch and mutate calls.

import crypto from '@aws-crypto/sha256-js';
import { SignatureV4 } from '@aws-sdk/signature-v4';
import type { HttpMessage, EndpointV2 } from '@aws-sdk/types';
import { HttpRequest } from '@aws-sdk/protocol-http';
import {
	APPSYNC_AWS_REGION,
	APPSYNC_AWS_ACCESS_KEY_ID,
	APPSYNC_AWS_SECRET_ACCESS_KEY,
} from '$env/static/private';

const { Sha256 } = crypto;
const GRAPHQL_ENDPOINT = import.meta.env.GRAPHQL_URL;
const AWS_REGION = APPSYNC_AWS_REGION || 'us-east-1';

const endpoint = new URL(GRAPHQL_ENDPOINT);

type HttpRequestOptions = Partial<HttpMessage> &
	Partial<EndpointV2> & {
		method?: string;
	};

const signer = new SignatureV4({
	credentials: {
		accessKeyId: APPSYNC_AWS_ACCESS_KEY_ID,
		secretAccessKey: APPSYNC_AWS_SECRET_ACCESS_KEY,
	},
	region: AWS_REGION,
	service: 'appsync',
	sha256: Sha256,
});

export async function serverGraphqlFetch(query: string, variables: { [k: string]: unknown }) {
	const options: HttpRequestOptions = {
		method: 'POST',
		hostname: endpoint.host,
		path: endpoint.pathname,
		headers: {
			'Content-Type': 'application/json',
			Host: endpoint.host,
		},
		body: JSON.stringify({
			query,
			variables,
		}),
	};

	const requestToBeSigned = new HttpRequest(options);
	const signed = await signer.sign(requestToBeSigned);
	const gqlRequest = new Request(endpoint, signed);
	return fetch(gqlRequest);
}

@rmarscher
Copy link
Contributor Author

Sorry that wasn't really any useful feedback. Just praise :-)

@AlecAivazis
Copy link
Collaborator

Oh don't worry - praise is fine too 😅

I'm super happy to hear you had an easy time adapting to the new world. I was mostly concerned about the overall complexity of having multiple phases, rules, terms, etc. but it sounds like you were able to navigate it well. Thanks for the feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants