Giter Site home page Giter Site logo

jointoucan / finch-graphql Goto Github PK

View Code? Open in Web Editor NEW
55.0 8.0 1.0 5.25 MB

Local GraphQL API in the background process of a web extension.

Home Page: https://jointoucan.github.io/finch-graphql/

License: MIT License

JavaScript 8.04% TypeScript 72.22% CSS 19.53% HTML 0.22%
graphql graphql-server graphql-api graphql-cli

finch-graphql's Introduction

Finch GraphQL

Finch GraphQL

Finch GraphQL is a library that allows you to build up a local GraphQL API that is accessible via client scripts of an web extension. When external messaging is setup you may even query Finch GraphQL from a connectable website.

Install

npm install --save @finch-graphql/api @finch-graphql/client graphql

If you are planning to use Finch GraphQL with react you can also install our React hooks

npm install --save @finch-graphql/react

How it works

Traditional implementation of GraphQL pass queries through HTTP, Finch GraphQL passes these queries though the browsers messaging system.

Diagram

Checkout an example extension.

Why?

Message passing is one of the main means of communication for content scripts to be able to access network request and access to local storage APIs like IndexDB. Using GraphQL gives you some powerful abilities when using this messaging.

  • Declarative: Imperative code can be hard to structure. Background scripts can become a confusing when imperatively connecting to events. GraphQL resolvers gives you structure on how to write your background script.
  • Error handling: If a error happens in the background script it will be surfaced to the client script. Writing code into resolvers GraphQL will catch the errors that happen on the background script.
  • Common patterns: GraphQL and React are common technology for the web, and when using them in a web extension it strips away some of the nuance of building an extension. This make extension development more accessible to backend and frontend developers.

Build out an API

The FinchApi class is a class that allows you to create an executable graphql schema. It is modeled to look just like the ApolloServer class. The only required properties in the options are typeDefs and resolvers.

import { FinchApi } from '@finch-graphql/api';

// Define your schema
const typeDefs = `
  input PermissionsInput {
    permissions: [String!]
  }

  type Browser {
    permissions($input: PermissionsInput)
  }

  type Query {
    browser: Browser
  }
`;

// Defined resolvers
const resolvers = {
  Browser: (parent, { input }) => {
    return browser.permissions.contains(input);
  },
};

// Create the executable schema
const api = new FinchApi({
  typeDefs,
  resolver,
});

Additional options

When initializing the api Finch has some options to be able to customize your API.

Option Type Description
messageKey string Use a custom message key instead of using the generic Finch-message
attachMessages boolean Auto attach browser messaging.
attachExternalMessages boolean Auto attach external browser messaging.
middleware MiddlewareFN[] Middleware provided by graphql-middleware
disableIntrospection boolean If true introspection queries will be turned off.
rules ValidationRules[] GraphQL validation rules

Attaching to messaging

If you do not have any existing messages you may use the attachMessages option to automatically attach to the runtime messages. If you have existing messages you will want to setup up the manual handler to ensure you are able to resolve async resolvers.

import { FinchMessageKey } from '@finch-graphql/types';

browser.runtime.on[External]Message.addListener(message => {
  if (message.type === FinchMessageKey.Generic) {
    return api.on[External]Message(message);
  }
}, []);

Query from content script

This is the main reason for this library, it makes it super easy to query large amounts of data from the background script without sending multiple messages.

import { FinchClient } from '@finch-graphql/client';

const client = new FinchClient();

const GetBrowserPermission = `
  query getBrowserPermission($input: PermissionsInput) {
    browser {
      permissions(input: $input)
    }
  }
`(async function main() {
  const resp = await client.query(GetBrowserPermission, {
    input: { permissions: ['geolocation'] },
  });

  if (resp.data?.browser?.permissions) {
    // Do stuff with permissions
  }
})();

React Hooks

There is two hooks available to use if you are using a React application. First is the useQuery hook.

import { useQuery } from '@finch-graphql/react';

const MyComponent = () => {
  const { data, error } = useQuery<QueryTypes, VariableTypes>(
    MyComponentQueryDoc,
    { variables: { enabled: true } }
  );

  if (error) {
    return null;
  }

  return (
    ...
  )
}

Testing

Testing between your background resolvers and client scripts is now super easy. Here is a snippet of code that will connect your background resolvers to the content scripts queries. Note this is using a jest mock.

import { backgroundApiInstance } from '~/background/graphql';

// This will connect the background resolvers to the client scripts when called.
export const connectBackgroundResolvers = () => {
  browser.runtime.sendMessage = jest
    .fn()
    .mockImplementation((message, sender) =>
      backgroundApiInstance.onMessage(message, sender),
    );
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.