GraphQL快速入门教程
摘要: 體驗(yàn)神奇的GraphQL!
原文:GraphQL 入門詳解
作者:MudOnTire
Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。
GraphQL簡(jiǎn)介
定義
一種用于API調(diào)用的數(shù)據(jù)查詢語(yǔ)言
核心思想
傳統(tǒng)的api調(diào)用一般獲取到的是后端組裝好的一個(gè)完整對(duì)象,而前端可能只需要用其中的某些字段,大部分?jǐn)?shù)據(jù)的查詢和傳輸工作都浪費(fèi)了。graphQL提供一種全新數(shù)據(jù)查詢方式,可以只獲取需要的數(shù)據(jù),使api調(diào)用更靈活、高效和低成本。
特點(diǎn)
需要什么就獲取什么數(shù)據(jù)
支持關(guān)系數(shù)據(jù)的查詢
API無(wú)需定義各種路由,完全數(shù)據(jù)驅(qū)動(dòng)
無(wú)需管理API版本,一個(gè)版本持續(xù)演進(jìn)
支持大部分主流開(kāi)發(fā)語(yǔ)言和平臺(tái)
強(qiáng)大的配套開(kāi)發(fā)工具
使用方法
下面我們通過(guò)搭建一個(gè)SpaceX的新聞網(wǎng)站來(lái)直觀學(xué)習(xí)graphQL的基本使用方法,所有數(shù)據(jù)由 官方API 獲得。
GraphQL服務(wù)端
服務(wù)端采用node + express。新建一個(gè)node項(xiàng)目,安裝如下依賴:
$ npm i graphql express-graphql express axios
創(chuàng)建入口文件 server.js,里面創(chuàng)建express服務(wù)。使用graphQL我們只需要設(shè)置一個(gè)路由,所有的請(qǐng)求都由這個(gè)graphQL的request handler處理:
const express = require("express");
const graphqlHTTP = require("express-graphql");
const schema = require("./schema");
const app = express();
app.use(
"/graphql",
graphqlHTTP({
schema,
graphiql: true
})
);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
graphqlHTTP是grapql的http服務(wù),用于處理graphql的查詢請(qǐng)求,它接收一個(gè)options參數(shù),其中schema是一個(gè) GraphQLSchema實(shí)例,我們接下來(lái)定義,graphiql設(shè)置為true可以在瀏覽器中直接對(duì)graphQL進(jìn)行調(diào)試。更多express-graphql的用法請(qǐng)參考 Github express-graphql。
schema
接下來(lái)我們定義schema,schema意為‘模式’,其中定義了數(shù)據(jù)模型的結(jié)構(gòu)、字段的類型、模型間的關(guān)系,是graphQL的核心。
新建schema.js文件,首先定義兩個(gè)數(shù)據(jù)模型:LaunchType(發(fā)射)和 RocketType(火箭)。注意字段的數(shù)據(jù)類型需要使用GraphQL定義的,不能使用js中的基本數(shù)據(jù)類型。
const {
GraphQLObjectType,
GraphQLInt,
GraphQLString,
GraphQLBoolean,
GraphQLList,
GraphQLSchema
} = require("graphql");
const LaunchType = new GraphQLObjectType({
name: "Launch",
fields: () => ({
flight_number: { type: GraphQLInt },
mission_name: { type: GraphQLString },
launch_date_local: { type: GraphQLString },
launch_success: { type: GraphQLBoolean },
rocket: { type: RocketType }
})
});
const LaunchType = new GraphQLObjectType({
name: "Rocket",
fields: () => ({
rocket_id: { type: GraphQLString },
rocket_name: { type: GraphQLString },
rocket_type: { type: GraphQLString }
})
});
有了數(shù)據(jù)模型之后,我們需要從數(shù)據(jù)庫(kù)或者第三方API獲取數(shù)據(jù),在此我們從spacex的官方API獲取。我們需要定義一個(gè)root query,root query做為所有查詢的入口,處理并返回?cái)?shù)據(jù),更多請(qǐng)參考 GraphQL Root fields & resolvers。
在 schema.js中增加代碼:
const axios = require("axios");
const RootQuery = new GraphQLObjectType({
name: "RootQueryType",
fields: {
launches: {
type: new GraphQLList(LaunchType),
resolve(parent, args) {
return axios
.get("https://api.spacexdata.com/v3/launches")
.then(res => res.data);
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
查詢列表
完成這一步,服務(wù)端api基本搭建完成!我們看一下效果,在瀏覽器中輸入 http://localhost:5000/graphql 將打開(kāi) Graphiql(生產(chǎn)環(huán)境建議禁用):
我們可以只查詢所有的 flight_number:
或者更多的屬性:
是不是很簡(jiǎn)單很神奇!
單個(gè)查詢
我們也可以通過(guò)傳入?yún)?shù)查詢單條信息:
const RootQuery = new GraphQLObjectType({
name: "RootQueryType",
fields: {
launch: {
type: LaunchType,
args: {
flight_number: { type: GraphQLInt }
},
resolve(parent, args) {
return axios
.get(
`https://api.spacexdata.com/v3/launches/${
args.flight_number
}`
)
.then(res => res.data);
}
}
}
});
結(jié)果:
推薦大家使用Fundebug,一款很好用的BUG監(jiān)控工具~
GraphQL前端
剛剛我們都是用GraphiQL在瀏覽器調(diào)用接口,接下來(lái)我們看一下在前端頁(yè)面中怎么調(diào)用graphql服務(wù)。前端我們使用react。
在項(xiàng)目根目錄初始化react項(xiàng)目:
$ npx create-react-app client
為了便于調(diào)試,在package.json中增加scripts:
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev":"concurrently "npm run server" "npm run client" "
樣式我們使用bootswatch中的一款主題:
GraphQL的客戶端有多種實(shí)現(xiàn),本次項(xiàng)目使用 Apollo,最流行的GraphQL Client。更多client請(qǐng)參考 GraphQL Clients。
安裝依賴
安裝如下依賴:
$ cd client
$ npm i apollo-boost react-apollo graphql
其中 apollo-boost 是apollo client本身,react-apollo 是react視圖層的集成,graphql 用于解析graphql的查詢語(yǔ)句。
設(shè)置client
修改App.js內(nèi)容如下:
import React, { Component } from "react";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";
import "./theme.css";
import "./App.css";
import logo from "./spacex-logo-light.png";
const client = new ApolloClient({
uri: "http://localhost:5000/graphql"
});
class App extends Component {
render() {
return (
<ApolloProvider client={client}>
<div className="container">
<img src={logo} id="logo" />
</div>
</ApolloProvider>
);
}
}
export default App;
和redux使用<Provider>傳遞store類似,react-apollo 通過(guò) <ApolloProvider>將apollo client向下傳遞。
實(shí)現(xiàn)query
接著我們來(lái)實(shí)現(xiàn)顯示launches的component,新增文件 components/Launches.js:
import React, { Component, Fragment } from "react";
import gql from "graphql-tag";
import { Query } from "react-apollo";
import LaunchItem from "./LaunchItem";
const LAUNCHES_QUERY = gql`
query LaunchesQuery {
launches {
flight_number
mission_name
launch_date_local
launch_success
}
}
`;
export class Launches extends Component {
render() {
return (
<Fragment>
<h1 className="display-4 my-3">Launches</h1>
<Query query={LAUNCHES_QUERY}>
{({ loading, error, data }) => {
if (loading) return <h4>Loading...</h4>;
if (error) console.log(error);
return (
<Fragment>
{data.launches.map(launch => (
<LaunchItem
key={launch.flight_number}
launch={launch}
/>
))}
</Fragment>
);
}}
</Query>
</Fragment>
);
}
}
export default Launches;
query語(yǔ)句通過(guò) graphql-tag 定義,傳入 <Query> 執(zhí)行獲取數(shù)據(jù)并傳入 LaunchItem 顯示。
components/LaunchItem.js:
import React from "react";
export default function LaunchItem({
launch: { flight_number, mission_name, launch_date_local, launch_success }
}) {
return (
<div className="card card-body mb-3">
<div className="col-md-9">
<h4>Mission: {mission_name}</h4>
<p>Date: {launch_date_local}</p>
</div>
<div className="col-md-3">
<button className="btn btn-secondary">Launch Details</button>
</div>
</div>
);
}
查詢語(yǔ)句通過(guò)graphql-tag定義,然后傳入<Query>執(zhí)行。
運(yùn)行
由于本地調(diào)試,client和server分別運(yùn)行在不同的端口,所以需要先進(jìn)行跨域處理,使用 cors。
// server.js
const cors = require('cors');
app.use(cors());
效果
好了,大功告成,我們來(lái)看一下效果:
結(jié)語(yǔ)
今天就主要介紹GraphQL工程的搭建和GraphQL Query的使用,更多關(guān)于GraphQL的內(nèi)容比如 Mutation下次有空會(huì)跟大家逐步講解。
本文靈感來(lái)源:Youtube@Traversy Media,感謝
本文Demo Github地址:Github@MudOnTire
本文Demo線上展示:http://t.zoukankan.com/Heroku@graphql-spacex-launches
最后,推薦大家使用Fundebug,一款很好用的BUG監(jiān)控工具~
關(guān)于Fundebug
Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應(yīng)用實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了10億+錯(cuò)誤事件,付費(fèi)客戶有陽(yáng)光保險(xiǎn)、核桃編程、荔枝FM、掌門1對(duì)1、微脈、青團(tuán)社等眾多品牌企業(yè)。歡迎大家免費(fèi)試用!
總結(jié)
以上是生活随笔為你收集整理的GraphQL快速入门教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: kafka的offset笔记
- 下一篇: 尝鲜党:Nexus5、6刷安卓M教程