Skip to content

Instantly share code, notes, and snippets.

@dburles
dburles / optimal-rest-api-design-for-graphql-with-dataloader.md
Created October 31, 2023 01:44
An approach to designing REST API’s to optimise requests made from a GraphQL server in combination with DataLoader.

Optimal REST API design for GraphQL with DataLoader

This document outlines an approach to designing REST API’s to optimise requests made from a GraphQL server in combination with DataLoader.

Entity relationships

Entities should always include their own id.

One-to-one relationships should be exposed through a field on the entity and never through denormalisation.

@dburles
dburles / module-server.js
Last active February 3, 2022 22:38
Proof-of-concept Deno HTTP server that parallelises requests for JavaScript modules using `modulepreload` in a `link` header.
// A simple proof-of-concept Deno HTTP server that parallelises requests for JavaScript modules.
// This is achieved by resolving the module graph for each requested resource
// using Deno graph (https://github.com/denoland/deno_graph).
// The result is converted into a `link` header (https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/modulepreload).
// For example, if 'a.js' imports 'b.js' and 'b.js' imports 'c.js' (and so on..),
// a request for 'a.js' will yield the following `link` header:
// <http://domain/b.js>; rel="modulepreload", <http://domain/c.js>; rel="modulepreload", <http://domain/d.js>; rel="modulepreload"
// In turn, the requests for module a's dependencies are made together.
// https://codesandbox.io/s/createsuspendevent-7yuzl?file=/src/Test.js
const createSuspendEvent = (fn) => {
return () => {
createResource(() => {
return new Promise((resolve) => {
fn((cleanup) => {
if (typeof cleanup === 'function') {
cleanup();
}
resolve();
const isIE11 = typeof window !== 'undefined' && !!window.msCrypto;
@dburles
dburles / _app.js
Created May 21, 2020 08:53
Next.js configuration for Mystical v2
import { MysticalProvider } from 'mystical';
import PropTypes from 'prop-types';
import theme from '../lib/theme';
const App = ({ Component, pageProps, cache }) => {
return (
<MysticalProvider theme={theme} cache={cache}>
<Component {...pageProps} />
</MysticalProvider>
);
@dburles
dburles / _app.js
Created May 19, 2020 08:12
Next.js configuration for Mystical
import { MysticalProvider } from 'mystical';
import PropTypes from 'prop-types';
const App = ({ Component, pageProps, cache }) => {
return (
<MysticalProvider cache={cache}>
<Component {...pageProps} />
</MysticalProvider>
);
};
import React, { useState, useRef, forwardRef, useEffect } from 'react';
import { createPortal } from 'react-dom';
const useEnsuredForwardedRef = forwardedRef => {
const ensuredRef = useRef(forwardedRef && forwardedRef.current);
useEffect(() => {
if (!forwardedRef) {
return;
}
import hashSum from 'hash-sum';
import React from 'react';
const camelDash = (string) =>
string.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);
const construct = (object) =>
Object.keys(object)
.map((key) => `${camelDash(key)}:${object[key]};`)
.join('');
import React, { useRef, useEffect, useState, useLayoutEffect } from 'react';
let globalIdentifier = 0;
const camelDash = string =>
string.replace(/([A-Z])/g, g => `-${g[0].toLowerCase()}`);
const construct = object =>
Object.keys(object)
.map(key => `${camelDash(key)}:${object[key]};`)