From 3d9da4dc2900e6348d908a11e505519332b47053 Mon Sep 17 00:00:00 2001 From: unicodeveloper Date: Wed, 3 Oct 2018 13:42:41 +0100 Subject: [PATCH] Add datasource content for REST API --- docs/source/tutorial/data-source.md | 104 +++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/docs/source/tutorial/data-source.md b/docs/source/tutorial/data-source.md index 890b2b3..e195503 100644 --- a/docs/source/tutorial/data-source.md +++ b/docs/source/tutorial/data-source.md @@ -38,8 +38,108 @@ export class MvrpAPI extends RESTDataSource { }; ``` -The `https://mvrp.herokuapp.com/api/` endpoint is a simple REST API that returns data for cars. +The `https://mvrp.herokuapp.com/api/` endpoint is a simple REST API that returns data for cars. Furthermore, the `MvrpAPI` class implementation in the code above contains a `getAllCars` and `getACar` functions that wrap convenience methods provided by the `RESTDataSource` class for performing HTTP requests. In this example, the built-in `get` method used is responsible for `GET` requests. + +Now that you have an understanding of how data sources work, let's hook it up for our tutorial app. + +Create a new `datasources` folder inside the `src` directory. This folder will contain our data source files. Now, create `launch.js` within the `datasources` directory. + +The REST API endpoint we'll use for our app is `https://api.spacexdata.com/v2/`. Add the endpoint as a base URL as shown in the code below: + +_src/datasources/launch.js_ + +```js +const { RESTDataSource } = require('apollo-datasource-rest'); + +class LaunchAPI extends RESTDataSource { + constructor() { + super(); + this.baseURL = 'https://api.spacexdata.com/v2/'; + } +} + +module.exports = LaunchAPI; +``` + +The next step is to add methods to the `LaunchAPI` class that corresponds to the type of queries our UI will fetch from the server. According to our app specifications, we'll need to get all launches, and get a specific launch. So, let's take care of getting all launches. + +```js +... +async getAllLaunches() { + const res = await this.get('launches'); + + return res.map(launch => { + return { + id: launch.flight_number || 0, + cursor: `${launch.flight_number || 0}-${launch.mission_name}`, + mission: { + name: launch.mission_name, + patch: null, // what to do here? + }, + year: launch.launch_year, + date: launch.launch_date_unix, + rocket: { + id: launch.rocket.rocket_id, + name: launch.rocket.rocket_name, + type: launch.rocket.rocket_type, + }, + launchSuccess: launch.launch_success, + }; + }); +} +``` + +In the code above, `this.get('launches')`, makes a `GET` request to `https://api.spacexdata.com/v2/launches` and stores the returned data in the `res` variable. The `getAllLaunches` method then returns an object that corresponds with the schema fields of the `Launch` schema type. + +Let's refactor the `getAllLaunches` method to be a lot cleaner and concise. + +```js +... +launchReducer(launch) { + return { + id: launch.flight_number || 0, + cursor: `${launch.flight_number || 0}-${launch.mission_name}`, + mission: { + name: launch.mission_name, + patch: null, // what to do here? + }, + year: launch.launch_year, + date: launch.launch_date_unix, + rocket: { + id: launch.rocket.rocket_id, + name: launch.rocket.rocket_name, + type: launch.rocket.rocket_type, + }, + launchSuccess: launch.launch_success, + }; +} + +async getAllLaunches() { + const res = await this.get('launches'); + + return res && res.length ? res.map(l => this.launchReducer(l)) : []; +} +``` + +With the above changes, we can easily make changes to the `launchReducer` method while the `getAllLaunches` method stays lean and concise. + +Now, let's take care of getting a specific launch. Add the following methods, `getLaunchById`, and `getLaunchesByIds` to the `LaunchAPI` class. + +```js +... +async getLaunchById({ launchId }) { + const res = await this.get('launches', { flight_number: launchId }); + return this.launchReducer(res[0]); +} + +async getLaunchesByIds({ launchIds }) { + return Promise.all( + launchIds.map(launchId => this.getLaunchById({ launchId })), + ); +} +``` + +The `getLaunchById` method takes in a flight number and returns the data for a particular launch, while `getLaunchesByIds` returns several launches based on their respective `launchIds`. `Promise.all()` takes an array of promises and returns a single promise that resolves when all the promises in the array have been resolved with their fulfilled values. -The `MvrpAPI` class implementation in the code above contains a `getAllCars` and `getACar` functions that wrap convenience methods provided by the `RESTDataSource` class for performing HTTP requests. In this example, we used the built-in `get` method that's responsible for `GET` requests.

Connect a database

\ No newline at end of file