babel-blade docs

babel-blade docs

  • Docs
  • API
  • Help
  • Blog

›Usage/API

Introduction

  • What is Babel-Blade?
  • The Double Declaration Problem

Getting Started

  • As a babel plugin
  • As a babel macro

Usage/API

  • GraphQL Spec By Example

GraphQL Spec By Example

On this page we show by example how to do every thing in the GraphQL query spec with babel-blade. These are directly tested for in our snapshot tests.

After you have tagged a data object with your query created with createQuery, it becomes a blade:


import {Connect, query} from 'urql'
import { createQuery } from 'blade.macro' // if you are using as a babel macro

const movieQuery = createQuery() // create the query
const Movie = () => (
  <div>
    <Connect
      query={query(movieQuery)}
      children={({data}) => {
        const DATA = movieQuery(data) // `DATA` is a blade
        const { schedule } = DATA // `schedule` is also a blade
        return (
          <div>
            <h2>{schedule.movie}</h2> 
          </div>
        )
      }}
    />
  </div>
)

Fields

After you have tagged a data object with your query created with createQuery, any property you access (including with destructuring) will be included in the generated GraphQL query.

Note: Known holes we intend to fix - array methods like .map and .forEach don't work yet.


import {Connect, query} from 'urql'
import { createQuery } from 'blade.macro' // if you are using as a babel macro

const movieQuery = createQuery()
const Movie = () => (
  <div>
    <Connect
      query={query(movieQuery)}
      children={({data}) => {
        const DATA = movieQuery(data) // key step
        return (
          <div>
            <h2>{DATA.movie.gorilla}</h2>
            <p>{DATA.movie.monkey}</p>
            <p>{DATA.chimp}</p>
          </div>
        )
      }}
    />
  </div>
)

      ↓ ↓ ↓ ↓ ↓ ↓

import { Connect, query } from 'urql';

const Movie = () => <div>
    <Connect query={query(`
query movieQuery{
  movie {
    gorilla
    monkey
  }
  chimp
}`)} children={({ data }) => {
    const DATA = data;
    return <div>
            <h2>{DATA.movie.gorilla}</h2>
            <p>{DATA.movie.monkey}</p>
            <p>{DATA.chimp}</p>
          </div>;
  }} />
  </div>;

Arguments

Every blade property can take arguments as though it were a function call - this gets moved to the generated GraphQL.


import {Connect, query} from 'urql'
import { createQuery } from 'blade.macro' // if you are using as a babel macro

const movieQuery = createQuery()
const Movie = () => (
  <div>
    <Connect
      query={query(movieQuery)}
      children={({data}) => {
        const DATA = movieQuery(data)
        const film = DATA.movie('limit: 5')
        const nestedQuery = film.schedule('schedule: true')
        return (
          <div>
            <Films data={film.titles} />
            <Schedule data={nestedQuery.data} />
          </div>
        )
      }}
    />
  </div>
)

      ↓ ↓ ↓ ↓ ↓ ↓

import { Connect, query } from 'urql';

const Movie = () => <div>
    <Connect query={query(`
query movieQuery{
  movie_19e8: movie(limit: 5) {
    schedule_7d17: schedule(schedule: true) {
      data
    }
    titles
  }
}`)} children={({ data }) => {
    const DATA = data;
    const film = DATA.movie_19e8;
    const nestedQuery = film.schedule_7d17;
    return <div>
            <Films data={film.titles} />
            <Schedule data={nestedQuery.data} />
          </div>;
  }} />
  </div>;

Aliases

Done for you!

Each arguments call gets an autogenerated 4 character hex alias to help distinguish between them. This way you don't have to manually assign aliases for multiple queries on the same fields but with different arguments.

Fragments

Use the createFragment pseudofunction to create the fragment, and then attach it as an argument to any blade property.

import {Connect, query} from 'urql'
import { createQuery } from 'blade.macro' // if you are using as a babel macro

// MovieComponent.js
const movieFragment = createFragment('Movie');
const Movie = ({ data }) => {
  let result = movieFragment(data);
  let movie = result.movie;
  return (
    <div className="movie">
      {loaded === false ? (
        <p>Loading</p>
      ) : (
        <div>
          <h2>{movie.title}</h2>
          <p>{movie.actors.supporting}</p>
          <p>{movie.actors.leading}</p>
          <button onClick={onClose}>Close</button>
        </div>
      )}
    </div>
  );
};

Movie.fragment = movieFragment;

// MoviePage.js
const pageQuery = createQuery(); // create a top-level query
const App = () => (
  <Connect
    query={query(pageQuery)}
    children={({ loaded, data }) => {
      let result = pageQuery(data);
      // rendering Movie while adding
      // `Movie.fragment` into the query.
      // (could be automatic in future)
      return (
        <ul>
          <Movie data={result.movie(null, Movie.fragment)} />
        </ul>
      );
    }}
  />
);

This transpiles to:

import {Connect, query} from 'urql'
const Movie = ({ data }) => {
  let result = data;
  let movie = result.movie;
  return (
    <div className="movie">
      {loaded === false ? (
        <p>Loading</p>
      ) : (
        <div>
          <h2>{movie.title}</h2>
          <p>{movie.actors.supporting}</p>
          <p>{movie.actors.leading}</p>
          <button onClick={onClose}>Close</button>
        </div>
      )}
    </div>
  );
};

Movie.fragment = movieFragment => `
fragment ${movieFragment} on Movie{
  movie {
    title
    actors {
      supporting
      leading
    }
  }
}`;

const App = () => (
  <Connect
    query={query(`
query pageQuery{
  movie {
    ...Moviefragment
  }
}

${Movie.fragment("Moviefragment")}`)}
    children={({ loaded, data }) => {
      let result = data;
      // rendering Movie while adding
      // `Movie.fragment` into the query.
      // (could be automatic in future)
      return (
        <ul>
          <Movie data={result.movie} />
        </ul>
      );
    }}
  />
);

Operation Name

All queries are named by whatever variable identifier you assign.

import {Connect, query} from 'urql'
import { createQuery } from 'blade.macro' // if you are using as a babel macro

const movieQuery = createQuery() // movieQuery becomes the operation name
const Movie = () => (
  <div>
    <Connect
      query={query(movieQuery)}
      children={({data}) => {
        const DATA = movieQuery(data)
        return (
          <div>
            <h2>{DATA.movie.gorilla}</h2>
            <p>{DATA.movie.monkey}</p>
            <p>{DATA.chimp}</p>
          </div>
        )
      }}
    />
  </div>
)

      ↓ ↓ ↓ ↓ ↓ ↓

import { Connect, query } from 'urql';

const Movie = () => <div>
    <Connect query={query(`
query movieQuery{
  movie {
    gorilla
    monkey
  }
  chimp
}`)} children={({ data }) => {
    const DATA = data;
    return <div>
            <h2>{DATA.movie.gorilla}</h2>
            <p>{DATA.movie.monkey}</p>
            <p>{DATA.chimp}</p>
          </div>;
  }} />
  </div>;

Variables

Supply variables as a string or template string to your createQuery call.


import {Connect, query} from 'urql'

const movieID = 12
const movieQuery = createQuery(`$movieID: ${movieID}`)
const Movie = () => (
  <div>
    <Connect
      query={query(movieQuery)}
      children={({data}) => {
        const DATA = movieQuery(data)
        return (
          <div>
            <h2>{DATA.movie('id: movieID')}</h2>
            <p>{DATA.movie.monkey}</p>
            <p>{DATA.chimp}</p>
          </div>
        )
      }}
    />
  </div>
)

      ↓ ↓ ↓ ↓ ↓ ↓

import { Connect, query } from 'urql';

const movieID = 12;

const Movie = () => <div>
    <Connect query={query(`
query movieQuery(${`$movieID: ${movieID}`}){
  movie_3d71: movie(id: movieID)
  movie {
    monkey
  }
  chimp
}`)} children={({ data }) => {
    const DATA = data;
    return <div>
            <h2>{DATA.movie_3d71}</h2>
            <p>{DATA.movie.monkey}</p>
            <p>{DATA.chimp}</p>
          </div>;
  }} />
  </div>;

Directives

Sorry.. this is not implemented yet. Contact @swyx or file an issue!

Mutations

Sorry.. this is not implemented yet. Contact @swyx or file an issue!

Inline Fragments

Sorry.. this is not implemented yet. Contact @swyx or file an issue!

← As a babel macro
  • Arguments
  • Aliases
  • Fragments
  • Operation Name
  • Variables
  • Directives
  • Mutations
  • Inline Fragments
babel-blade docs
Docs
Getting Started (or other categories)Guides (or other categories)API Reference (or other categories)
Community
User ShowcaseStack OverflowProject ChatTwitter
More
BlogGitHubStar
Facebook Open Source
Copyright © 2018 Your Name or Your Company Name