diff --git a/.gitignore b/.gitignore index 37d7e73..3c3629e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ node_modules -.env diff --git a/README.md b/README.md index 0608aaf..e9d1792 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,21 @@ -globe +

+ globe +

-# Countries GraphQL API +

Countries GraphQL API

+ +
[![Build Status](https://github.com/trevorblades/countries/workflows/Node%20CI/badge.svg)](https://github.com/trevorblades/countries/actions) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md) +[![Twitter Follow](https://img.shields.io/twitter/follow/trevorblades?style=social)](https://twitter.com/trevorblades) + +
A public GraphQL API for information about countries, continents, and languages. This project uses [Countries List](https://annexare.github.io/Countries/) and [`provinces`](https://github.com/substack/provinces) as data sources, 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. +2. The `country.continent` and `country.languages` are now objects and arrays of objects, respectively. 3. Each `Country` has an array of `states` populated by their states/provinces, if any. ## Writing queries @@ -18,6 +25,7 @@ A public GraphQL API for information about countries, continents, and languages. country(code: "BR") { name native + capital emoji currency languages { @@ -36,6 +44,7 @@ The above GraphQL query will produce the following JSON response: "country": { "name": "Brazil", "native": "Brasil", + "capital": "Brasília", "emoji": "🇧🇷", "currency": "BRL", "languages": [ @@ -49,6 +58,8 @@ The above GraphQL query will produce the following JSON response: } ``` +## Docs + Check out [the playground](https://countries.trevorblades.com) to explore the schema and test out some queries. ## Examples @@ -58,6 +69,7 @@ Check out [the playground](https://countries.trevorblades.com) to explore the sc - [ReasonML](https://medium.com/@idkjs/reasonml-and-graphql-without-graphql-part-1-192c2e9e349c) - [Country quiz app](https://github.com/byrichardpowell/Country-Quiz) (React, TypeScript) - [Python](./examples/python) +- [Seed](https://github.com/seed-rs/seed/tree/master/examples/graphql) ## License diff --git a/apollo.config.js b/apollo.config.js deleted file mode 100644 index c2e2a4d..0000000 --- a/apollo.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - endpoint: { - url: `http://localhost:${process.env.PORT}` - } -}; diff --git a/index.js b/index.js index 515755b..5804872 100644 --- a/index.js +++ b/index.js @@ -4,44 +4,45 @@ const {continents, countries, languages} = require('countries-list'); const typeDefs = gql` type Continent { - code: String - name: String - countries: [Country] + code: ID! + name: String! + countries: [Country!]! } type Country { - code: String - name: String - native: String - phone: String - continent: Continent - currency: String - languages: [Language] - emoji: String - emojiU: String - states: [State] + code: ID! + name: String! + native: String! + phone: String! + continent: Continent! + capital: String! + currency: String! + languages: [Language!]! + emoji: String! + emojiU: String! + states: [State!]! } type State { code: String - name: String - country: Country + name: String! + country: Country! } type Language { - code: String + code: ID! name: String native: String - rtl: Int + rtl: Boolean! } type Query { - continents: [Continent] - continent(code: String!): Continent - countries: [Country] - country(code: String!): Country - languages: [Language] - language(code: String!): Language + continents: [Continent!]! + continent(code: ID!): Continent + countries: [Country!]! + country(code: ID!): Country + languages: [Language!]! + language(code: ID!): Language } `; @@ -84,12 +85,20 @@ const resolvers = { })); } }, + Language: { + rtl(language) { + return Boolean(language.rtl); + } + }, Query: { continent(parent, {code}) { - return { - code, - name: continents[code] - }; + const name = continents[code]; + return ( + name && { + code, + name + } + ); }, continents() { return Object.entries(continents).map(([code, name]) => ({ @@ -99,10 +108,12 @@ const resolvers = { }, country(parent, {code}) { const country = countries[code]; - return { - ...country, - code - }; + return ( + country && { + ...country, + code + } + ); }, countries() { return Object.entries(countries).map(([code, country]) => ({ @@ -112,10 +123,12 @@ const resolvers = { }, language(parent, {code}) { const language = languages[code]; - return { - ...language, - code - }; + return ( + language && { + ...language, + code + } + ); }, languages() { return Object.entries(languages).map(([code, language]) => ({ @@ -136,6 +149,6 @@ const server = new ApolloServer({ } }); -server.listen({port: process.env.PORT}).then(({url}) => { +server.listen({port: process.env.PORT || 4000}).then(({url}) => { console.log(`🚀 Server ready at ${url}`); }); diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..a5b6c63 Binary files /dev/null and b/logo.png differ diff --git a/package.json b/package.json index df2dcd8..8e1ede2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "scripts": { - "start": "nodemon -r dotenv/config index.js", - "pretest": "eslint index.js apollo.config.js", + "start": "nodemon index.js", + "pretest": "eslint index.js", "test": "echo \"Error: no test specified\" && exit" }, "eslintConfig": {