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!