GraphQL, built for Deno - a native GraphQL caching client and server module
MIT License
Obsidian is Deno's first native GraphQL caching client and server module. Boasting lightning-fast caching and fetching capabilities alongside headlining normalization and rebuilding strategies, Obsidian is equipped to support scalable, highly performant applications.
With additional support for use in server-side rendered React apps built with Deno, full stack integration of Obsidian enables a fast and flexible caching solution.
import { Application, Router } from 'https://deno.land/x/[email protected]/mod.ts';
import { ObsidianRouter, gql } from 'https://deno.land/x/obsidian/mod.ts';
import { resolvers } from './ import from your resolvers file';
import { types } from './ import your schema/types from schema/types file';
interface ObsRouter extends Router {
obsidianSchema?: any;
}
const GraphQLRouter =
(await ObsidianRouter) <
ObsRouter >
{
Router, // your router in deno
typeDefs: types, // graphQL typeDefs
resolvers: resolvers, // graphQL resolvers
};
// attach the graphql router's routes to your deno app
app.use(GraphQLRouter.routes(), GraphQLRouter.allowedMethods());
const GraphQLRouter =
(await ObsidianRouter) <
ObsRouter >
{
Router, // Router that is initialized by server.
path: '/graphql', // endpoint for graphQL queries, default to '/graphql'
typeDefs: types, // graphQL typeDefs
resolvers: resolvers, // graphQL resolvers
usePlayground: true, // Boolean to allow for graphQL playground, default to false
useCache: true, // Boolean to toggle all cache functionality, default to true
redisPort: 6379, // Desired redis port, default to 6379
policy: 'allkeys-lru', // Option select your Redis policy, default to allkeys-lru
maxmemory: '2000mb', // Option to select Redis capacity, default to 2000mb
searchTerms: [] //Optional array to allow broad queries to store according to search fields so individual searches are found in cache
persistQueries: true, //Boolean to toggle the use of persistent queries, default to false - NOTE: if using, must also be enabled in client wrapper
hashTableSize: 16, // Size of hash table for persistent queries, default to 16
maxQueryDepth: 0, // Maximum depth of query, default to 0
customIdentifier: ['__typename', '_id'], // keys to be used to idedntify and normalize object
mutationTableMap: {}, //Object where keys are add mutation types and value is an array of affected tables (e.g. {addPlants: ['plants'], addMovie: ['movies']})
};
import { ObsidianWrapper } from 'https://deno.land/x/obsidian/clientMod.ts';
const App = () => {
return (
<ObsidianWrapper>
<MovieApp />
</ObsidianWrapper>
);
};
<ObsidianWrapper
useCache={true} // Boolean indicating whether to use client-side cache, default to true
algo='LRU' // String indicating cache policy to use for client-side cache, default to LFU. OTHER OPTIONS: W-Tiny-LFU, LRU
capacity='5000' // String indicating numeric capacity of cache, default to 2000
persistQueries={true} // Boolean indicating wheter to use persistent queries, default to false
searchTerms={['title', 'director', 'genre']} // Optional parameter to set search terms of the data
>
<MovieApp />
</ObsidianWrapper>
import { useObsidian } from 'https://deno.land/x/obsidian/clientMod.ts';
const MovieApp = () => {
const { query } = useObsidian();
const [movies, setMovies] = (React as any).useState('');
const queryStr = `query {
movies {
id
title
releaseYear
genre
}
}
`;
return (
<h1>{movies}</h1>
<button
onClick={() => {
query(queryStr)
.then(resp => setMovies(resp.data))
}}
>Get Movies</button>
);
};
import { useObsidian } from 'https://deno.land/x/obsidian/clientMod.ts';
const MovieApp = () => {
const { mutate } = useObsidian();
const [movies, setMovies] = (React as any).useState('');
const queryStr = `mutation {
addMovie(input: {title: "Cruel Intentions", releaseYear: 1999, genre: "DRAMA" }) {
id
title
releaseYear
genre
}
}
`;
return (
<h1>{movies}</h1>
<button
onClick={() => {
mutate(queryStr)
.then(resp => setMovies(resp.data))
}}
>Get Movies</button>
);
}
In order to utilize server side caching, a Redis instance must be available and running. Redis installation and quick-start documentation can be found here. Make sure to keep a redis instance running whenever the application is utilizing server side caching to avoid running into issues.
To connect Obsidian to Redis, create a .env file in the root directory of the application with the following information:
REDIS_HOST= //string of redis host name, typically defaulted to '127.0.0.1' by Redis
Be sure to also specify the Redis TCP port by passing in the port number as an argument into Obsidian Router (see Selecting options for the Router above).
Information and instructions on how to use our developer tool can be found here works with Obsidian 8.0 open-source-labs/obsidian-developer-tool
Github for a demo with some example code to play with: oslabs-beta/obsidian-demo-8.0
David Kim David Norman Eileen Cho Joan Manto Alex Lopez Kevin Huang Matthew Weisker Ryan Ranjbaran Derek Okuno Liam Johnson Josh Reed Jonathan Fangon Liam Jeon Yurii Shchyrba Linda Zhao Ali Fay Anthony Guan Yasir Choudhury Yogi Paturu Michael Chin Dana Flury Sardor Akhmedov Christopher Berry Olivia Yeghiazarian Michael Melville John Wong Kyung Lee Justin McKay Patrick Sullivan Cameron Simmons Raymond Ahn Alonso Garza Burak Caliskan Matt Meigs Travis Frank Lourent Flores Esma Sahraoui Derek Miller Eric Marcatoma Spencer Stockton