All Projects → smooth-code → Fraql

smooth-code / Fraql

Licence: mit
GraphQL fragments made simple ⚡️

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Fraql

Graphql Query Test Mock
Easily mock GraphQL queries in your Relay Modern / Apollo / any-other-GraphQL-client tests.
Stars: ✭ 49 (-88.68%)
Mutual labels:  graphql, relay, apollographql, mocking
Graphql Up
Get a ready-to-use GraphQL API for your schema
Stars: ✭ 415 (-4.16%)
Mutual labels:  graphql, apollo, relay, apollographql
Get Graphql Schema
Fetch and print the GraphQL schema from a GraphQL HTTP endpoint. (Can be used for Relay Modern.)
Stars: ✭ 443 (+2.31%)
Mutual labels:  graphql, apollo, relay, apollographql
Link state demo
🚀 Demonstrate how to support multiple stores in Apollo Link State
Stars: ✭ 30 (-93.07%)
Mutual labels:  graphql, apollo, apollographql
Graphback
Graphback - Out of the box GraphQL server and client
Stars: ✭ 323 (-25.4%)
Mutual labels:  graphql, apollo, apollographql
Graphql React Apollo
A GraphQL implementation in React using Apollo.
Stars: ✭ 9 (-97.92%)
Mutual labels:  graphql, apollo, apollographql
Apollo Mocked Provider
Automatically mock GraphQL data with a mocked ApolloProvider
Stars: ✭ 70 (-83.83%)
Mutual labels:  graphql, apollo, apollographql
Apollo Prophecy
🔮 GraphQL error management made Easy, generate custom machine-readable errors for Apollo Client/Server from the CLI
Stars: ✭ 83 (-80.83%)
Mutual labels:  graphql, apollo, apollographql
Angular Fullstack Graphql
🚀 Starter projects for fullstack applications based on Angular & GraphQL.
Stars: ✭ 92 (-78.75%)
Mutual labels:  graphql, apollo, apollographql
React Fullstack Graphql
Starter projects for fullstack applications based on React & GraphQL.
Stars: ✭ 1,352 (+212.24%)
Mutual labels:  graphql, apollo, apollographql
Graphql Ws
Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client.
Stars: ✭ 398 (-8.08%)
Mutual labels:  graphql, apollo, relay
Graphql
GraphQL (TypeScript) module for Nest framework (node.js) 🍷
Stars: ✭ 697 (+60.97%)
Mutual labels:  graphql, apollo, apollographql
Offix
GraphQL Offline Client and Server
Stars: ✭ 694 (+60.28%)
Mutual labels:  graphql, apollo, apollographql
Graphql Config
One configuration for all your GraphQL tools (supported by most tools, editors & IDEs)
Stars: ✭ 883 (+103.93%)
Mutual labels:  graphql, apollo, relay
Js Graphql Intellij Plugin
GraphQL language support for WebStorm, IntelliJ IDEA and other IDEs based on the IntelliJ Platform.
Stars: ✭ 686 (+58.43%)
Mutual labels:  graphql, apollo, relay
Learnapollo
👩🏻‍🏫 Learn Apollo - A hands-on tutorial for Apollo GraphQL Client (created by Graphcool)
Stars: ✭ 5,274 (+1118.01%)
Mutual labels:  graphql, apollo, apollographql
Relay Example
[READONLY] 💝 Examples of common Relay patterns used in real-world applications. This repository is automatically exported from https://github.com/adeira/universe via Shipit
Stars: ✭ 126 (-70.9%)
Mutual labels:  graphql, relay, fragment
Graphql Crunch
Reduces the size of GraphQL responses by consolidating duplicate values
Stars: ✭ 472 (+9.01%)
Mutual labels:  graphql, apollo, relay
Booben
Web app constructor based on React, with GraphQL bindings
Stars: ✭ 96 (-77.83%)
Mutual labels:  graphql, apollo, apollographql
React Graphql Github Apollo
🚀 A React + Apollo + GraphQL GitHub Client. Your opportunity to learn about these technologies in a real world application.
Stars: ✭ 1,563 (+260.97%)
Mutual labels:  graphql, apollo, apollographql

FraQL

GraphQL fragments made simple ⚡️

Build Status Code Coverage version MIT License

PRs Welcome

Watch on GitHub Star on GitHub Tweet

npm install fraql graphql graphql-tools graphql-tag

FraQL solves several things:

  • ☀️ Isolation: fragments don't rely on name anymore
  • ✨ Mocking: generate data & props from fragments
  • 🤯 Collocation: put GraphQL in your components

Example

import gql from 'fraql'

// Create fragment without naming it.
const fragment = gql`
  fragment _ on Article {
    title
    description
  }
`

// Just use it in your queries!
const query = gql`
  query Articles {
    articles {
      id
      ${fragment}
    }
  }
`

⚡️ See live example on CodeSandbox

Motivation

Putting data next to your component is a good practice. It is built-in Relay and Lee Byron explains the advantages into his talk about the IDEA architecture.

I tried to do it by myself, but relying on fragment names is not an easy task. FraQL solves this issue by bringing isolation, fragments do not rely on their names.

The second problem solved by FraQL is the mocking. Generating a set of data for complex components is a pain. FraQL solves it by generating data right from your fragments!

Usage with React

Reference fragments into components

FraQL exports a default tag function that is a drop-in replacement for graphql-tag. By using it you can create reusable fragments easily.

FraQL is not a framework, but it comes with good practices. It is recommended to create a static property fragments on your components that contains a map of component properties. For each one, you specify the associated fragment.

You may have noticed that the name of the fragment is "_". FraQL transforms your fragment into an inline fragment. You can pick any name you want, because it will be dropped the transformation anyway.

import React from 'react'
import gql from 'fraql'

const ArticleCard = ({ article }) => (
  <div>
    <h1>{article.title}</h1>
    <p>{article.description}</p>
  </div>
)

// Create a map of fragments and reference them on a static property "fragments".
ArticleCard.fragments = {
  article: gql`
    fragment _ on Article {
      title
      description
    }
  `,
}

export default ArticleCard

Use fragments into your queries

With FraQL, using a fragment into a query is obvious, just put the fragment where you want to use it.

Importing gql from fraql is not required for queries. In this case this is just a pass-through to graphql-tag. The magic behind FraQL only happens when you use it on a fragment.

import React from 'react'
import gql from 'fraql'
import { Query } from 'apollo-client'
import ArticleCard from './ArticleCard'

// Build your query by using your fragment.
const ARTICLES = gql`
  query Articles {
    articles {
      id
      ${ArticleCard.fragments.article}
    }
  }
`

const ArticleList = ({ articles }) => (
  <div>
    <Query query={ARTICLES}>
      {({ data }) =>
        data.articles &&
        data.articles.map(article => (
          <ArticleCard key={article.id} article={article} />
        ))
      }
    </Query>
  </div>
)

export default ArticleList

⚡️ See live example on CodeSandbox

⚡️ See React example in this repository

Mocking

Tools like StoryBook allows you to develop your components into an isolated environment. But you still have to write a set of data for displaying your components. Each time you modify your component, you have to modify this set of data, it is a real pain to maintain!

If all your components have fragments, you get mocking for free!

1. Generate introspection

Mocking data from a fragment requires knowing all schema types. That's why you have to generate a introspection result from your schema in order to use mocking.

FraQL exposes a method introspectSchema to simplify this operation. The only thing you have to do is create a script that dumps your introspection result into a JSON file.

// Example of script that generates an introspection result into "schema.json".
const { writeFileSync } = require('fs')
const { introspectSchema } = require('fraql/server')
const schema = require('./myGraphQLSchema') // Your schema defined server-side

const data = introspectSchema(schema)
fs.writeFileSync('schema.json', JSON.stringify(data))

2. Create a mocker

FraQL exposes a method createMockerFromIntrospection that creates a mocker from your schema.json.

It is recommended to create one mocker and to use it wherever you need to generate data.

// mocker.js
import { createMockerFromIntrospection } from 'fraql/mock'
import introspectionData from './schema.json'

export default createMockerFromIntrospection(introspectionData)

3. Mock your fragments

You can now mock fragments using mockFragment or mockFragments methods.

Single fragment

import gql from 'fraql'
import mocker from './mocker'

const fragment = gql`
  fragment _ on Article {
    id
    title
    author {
      name
    }
  }
`

const data = mocker.mockFragment(fragment)
// {
//   id: '4b165f7d-2ee1-4f09-8fd7-fc90d38a238a',
//   title: 'Hello World',
//   author: {
//     name: 'Hello World',
//   },
// }

Multiple fragments (components)

import React from 'react'
import gql from 'fraql'
import mocker from './mocker'
import ArticleCard from './ArticleCard'

// Generate all props directly from fragments.
const props = mocker.mockFragments(ArticleCard.fragments)

// Create an element using generated props.
const articleCard = <ArticleCard {...props} />

⚡️ See StoryBook example in this repository

Recipes

Compose fragments

One of the principles of React is component composition. It is recommended to do the same with your GraphQL fragments.

// ArticleTitle.js
import React from 'react'
import gql from 'fraql'

const ArticleTitle = ({ article }) => <h2>{article.title}</h2>

ArticleTitle.fragments = {
  article: gql`
    fragment _ on Article {
      title
    }
  `,
}

export default ArticleTitle
// ArticleCard.js
import React from 'react'
import gql from 'fraql'
import ArticleTitle from './ArticleTitle'

const ArticleCard = ({ article }) => (
  <div>
    <ArticleTitle article={article} />
    <div>{article.text}</div>
  </div>
)

ArticleCard.fragments = {
  article: gql`
    fragment _ on Article {
      ${ArticleTitle.fragments.article}
      text
    }
  `,
}

export default ArticleCard

Use without gql

FraQL offers a drop-in replacement for graphql-tag but sometimes you don't use gql to define your fragments. As mentioned in graphql-tag documentation there are lots of other ways to do it (using Babel, Webpack, etc..).

FraQL exposes a function toInlineFragment that transforms a GraphQL fragment into an inline fragment.

import { toInlineFragment } from 'fraql'
import gql from 'graphql-tag'
import fragment from './myFragment.gql'

const inlineFragment = toInlineFragment(fragment)

const query = gql`
  query {
    articles {
      ${inlineFragment}
    }
  }
`

Mix named and inline fragments

Sometimes you may want to have the best of the two worlds, use a named fragment in one query and an inline fragment in another.

For this specific use-case FraQL exposes the original document:

import gql from 'fraql'

const fragment = gql`
  fragment BaseArticleInfos on Article {
    title
    text
  }
`

const query = gql`
  query Articles {
    articles {
      ...BaseArticleInfos
    }
  }

  ${fragment.originalDocument}
`

Use custom mocks

Mocking feature of FraQL is build on top of graphql-tools, it means you can customize all your mocks.

You can define global mocks when you create the mocker:

import introspectionData from './schema.json'

const mocker = createMockerFromIntrospection(introspectionData, {
  mocks: {
    Article: () => ({
      title: 'My article title',
    }),
  },
})

And you can override them into mockFragment and mockFragments:

import ArticleCard from './ArticleCard'

const props = mocker.mockFragments(ArticleCard.fragments, {
  mocks: {
    Article: () => ({
      title: 'Another title',
    }),
  },
})

API

fraql / gql

The default export of fraql is a drop-in replacement for graphql-tag that automatically converts fragments into inline fragments.

import gql from 'fraql'

const inlineFragment = gql`
  fragment _ on Article {
    title
  }
`

const query = gql`
  {
    articles {
      id
      ${inlineFragment}
    }
  }
`

toInlineFragment(fragmentDocument)

Converts a fragment into an inline fragment usable in requests.

import gql from 'graphql-tag'
import { toInlineFragment } from 'fraql'

const fragment = gql`
  fragment ArticleTitle on Article {
    title
  }
`

const inlineFragment = toInlineFragment(fragment)

const query = gql`
  {
    articles {
      id
      ${inlineFragment}
    }
  }
`

introspectSchema(schema)

Generates introspection data from a schema.

import { introspectSchema } from 'fraql/server'
import schema from './graphqlSchema'

const introspectionData = introspectSchema(schema)

createMockerFromIntrospection(introspectionData, { mocks } = {})

Generates a mocker from an introspection result generated using introspectSchema.

You can specify mocks, using the same format as graphql-tools.

import { createMockerFromIntrospection } from 'fraql/mock'
import introspectionData from './schema.json'

const mocker = createMockerFromIntrospection(introspectionData)

mocker.mockFragment(fragment, { mocks } = {})

Generates mock data from one fragment.

You can specify mocks, using the same format as graphql-tools.

const fragment = gql`
  fragment _ on Article {
    title
  }
`

const data = fraqlMocker.mockFragment(fragment)
// { title: 'Hello World' }

mocker.mockFragments(fragments, { mocks } = {})

Generates mock data from a map of fragments.

You can specify mocks, using the same format as graphql-tools.

const fragments = {
  article: gql`
    fragment _ on Article {
      title
      author {
        name
      }
    }
  `,
  book: gql`
    fragment _ on Book {
      title
    }
  `,
}

const data = fraqlMocker.mockFragment(fragments)
// {
//   article: {
//     title: 'Hello World',
//     author: {
//       name: 'Hello World',
//     },
//   },
//   book: {
//     title: 'Hello World',
//   }
// }

Inspiration & Thanks

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].