mirror of
https://github.com/zhigang1992/apollo.git
synced 2026-05-12 08:15:31 +08:00
Add datasource content for REST API
This commit is contained in:
committed by
Peggy Rayzis
parent
f8cb4af23d
commit
3d9da4dc29
@@ -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.
|
||||
|
||||
<h2 id="database">Connect a database</h2>
|
||||
Reference in New Issue
Block a user