Add example code

This commit is contained in:
Trevor Blades
2018-11-09 16:55:20 -08:00
parent ea8a14cc28
commit 0fd748b792

View File

@@ -4,12 +4,14 @@
[![Donate](https://img.shields.io/beerpay/trevorblades/countries.svg)](https://beerpay.io/trevorblades/countries)
A public GraphQL API for information about countries, continents, and languages. This project uses [Countries List](https://annexare.github.io/Countries/) as a data source, so the schema follows the shape of that data, with a couple exceptions:
A public GraphQL API for information about countries, continents, and languages. This project uses [Countries List](https://annexare.github.io/Countries/) as a data source, so the schema follows the shape of that data, with a few exceptions:
1. The codes used to key the objects in the original data are available as a `code` property on each item returned from the API.
2. The `continent` and `languages` properties are now objects and arrays of objects, respectively.
## Writing queries
## Querying
In:
```graphql
{
@@ -26,6 +28,8 @@ A public GraphQL API for information about countries, continents, and languages.
}
```
Out:
```json
{
"data": {
@@ -45,30 +49,38 @@ A public GraphQL API for information about countries, continents, and languages.
}
```
Check out the [playground](https://countries.trevorblades.com) to explore the schema and test out some queries.
Check out [the playground](https://countries.trevorblades.com) to explore the schema and test out some queries.
## Example
A practical use of this API is to create a country select input that doesn't require you to include a large dataset of country info in your bundle.
One practical use of this API is to create a country select field that fetches its options dynamically. Normally, you would need to install an npm package or create a file in your project containing the necessary data -- usually country codes and names -- and bundle that data with your app code. This results in a lot of extra kilobytes hanging around in your bundle for a feature that might not always get rendered or used. Here's what that data size looks like:
In this example, we'll be using [React](https://reactjs.org/) and the [Apollo](https://apollographql.com) GraphQL client. First, we'll install all of our dependencies:
- **50.1 KB** using the `countries` export from [Countries List](https://annexare.github.io/Countries/)
- **14.2 KB** using this API (~70% smaller)
In this example, I'll be using [React](https://reactjs.org/) and some [Apollo](https://apollographql.com) tools. Apollo's GraphQL client and React components make it simple to execute, handle, and cache GraphQL queries. You can also accomplish this by sending a POST request to this API using `fetch` or your favourite request library, but I won't cover that in this example.
### Install dependencies
```shell
$ npm install react react-dom react-apollo apollo-boost graphql graphql-tag
```
50.1 KB with `countries-list`
14.2 KB with Countries GraphQL
### Build a React component
```js
import React from 'react';
import ReactDOM from 'react-dom';
import ApolloClient from 'apollo-boost';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import gql from 'graphql-tag';
import {Query} from 'react-apollo';
// initialize our Apollo GraphQL client
const client = new ApolloClient({
uri: 'https://countries.trevorblades.com'
});
// write a GraphQL query that asks for names and codes for all countries
const GET_COUNTRIES = gql`
{
countries {
@@ -79,38 +91,45 @@ const GET_COUNTRIES = gql`
`;
class App extends Component {
state = {
country: ''
};
constructor(props) {
super(props);
onCountryChange = event =>
// set a default value
this.state = {
country: 'US'
};
}
// set the selected country to the new input value
onCountryChange(event) {
this.setState({country: event.target.value});
}
render() {
return (
<ApolloProvider client={client}>
<Query query={GET_COUNTRIES}>
{({loading, error, data}) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>{error.message}</p>;
return (
<select
value={this.state.country}
onChange={this.onCountryChange}
>
{data.countries.map(country => (
<option key={country.code} value={country.code}>
{country.name}
</option>
))}
</select>
);
}}
</Query>
</ApolloProvider>
<Query query={GET_COUNTRIES} client={client}>
{({loading, error, data}) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>{error.message}</p>;
return (
<select
value={this.state.country}
onChange={this.onCountryChange.bind(this)}
>
{data.countries.map(country => (
<option key={country.code} value={country.code}>
{country.name}
</option>
))}
</select>
);
}}
</Query>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
```
### Behold, your mighty country select 🎉