GraphQL快速入門教程

来源:https://www.cnblogs.com/fundebug/archive/2019/07/29/quick-graphql-tutorial.html
-Advertisement-
Play Games

摘要: 體驗神奇的GraphQL! 原文: "GraphQL 入門詳解" 作者:MudOnTire "Fundebug" 經授權轉載,版權歸原作者所有。 GraphQL簡介 定義 一種用於API調用的數據查詢語言 核心思想 傳統的api調用一般獲取到的是後端組裝好的一個完整對象,而前端可能只需要用其 ...


摘要: 體驗神奇的GraphQL!

Fundebug經授權轉載,版權歸原作者所有。

GraphQL簡介

定義

一種用於API調用的數據查詢語言

核心思想

傳統的api調用一般獲取到的是後端組裝好的一個完整對象,而前端可能只需要用其中的某些欄位,大部分數據的查詢和傳輸工作都浪費了。graphQL提供一種全新數據查詢方式,可以只獲取需要的數據,使api調用更靈活、高效和低成本。

特點

  1. 需要什麼就獲取什麼數據
  2. 支持關係數據的查詢
  3. API無需定義各種路由,完全數據驅動
  4. 無需管理API版本,一個版本持續演進
  5. 支持大部分主流開發語言和平臺
  6. 強大的配套開發工具

使用方法

下麵我們通過搭建一個SpaceX的新聞網站來直觀學習graphQL的基本使用方法,所有數據由 官方API 獲得。

GraphQL服務端

服務端採用node + express。新建一個node項目,安裝如下依賴:

$ npm i graphql express-graphql express axios

創建入口文件 server.js,裡面創建express服務。使用graphQL我們只需要設置一個路由,所有的請求都由這個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服務,用於處理graphql的查詢請求,它接收一個options參數,其中schema是一個 GraphQLSchema實例,我們接下來定義,graphiql設置為true可以在瀏覽器中直接對graphQL進行調試。更多express-graphql的用法請參考 Github express-graphql

schema

接下來我們定義schema,schema意為‘模式’,其中定義了數據模型的結構、欄位的類型、模型間的關係,是graphQL的核心。

新建schema.js文件,首先定義兩個數據模型:LaunchType(發射)和 RocketType(火箭)。註意欄位的數據類型需要使用GraphQL定義的,不能使用js中的基本數據類型。

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 }
    })
});

有了數據模型之後,我們需要從資料庫或者第三方API獲取數據,在此我們從spacex的官方API獲取。我們需要定義一個root query,root query做為所有查詢的入口,處理並返回數據,更多請參考 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
});

查詢列表

完成這一步,服務端api基本搭建完成!我們看一下效果,在瀏覽器中輸入 http://localhost:5000/graphql 將打開 Graphiql(生產環境建議禁用):

我們可以只查詢所有的 flight_number

或者更多的屬性:

是不是很簡單很神奇!

單個查詢

我們也可以通過傳入參數查詢單條信息:

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);
            }
        }
    }
});

結果:

推薦大家使用Fundebug,一款很好用的BUG監控工具~

GraphQL前端

剛剛我們都是用GraphiQL在瀏覽器調用介面,接下來我們看一下在前端頁面中怎麼調用graphql服務。前端我們使用react。

在項目根目錄初始化react項目:

$ npx create-react-app client

為了便於調試,在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的客戶端有多種實現,本次項目使用 Apollo,最流行的GraphQL Client。更多client請參考 GraphQL Clients

安裝依賴

安裝如下依賴:

$ cd client
$ npm i apollo-boost react-apollo graphql

其中 apollo-boost 是apollo client本身,react-apollo 是react視圖層的集成,graphql 用於解析graphql的查詢語句。

設置client

修改App.js內容如下:

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 通過 <ApolloProvider>將apollo client向下傳遞。

實現query

接著我們來實現顯示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語句通過 graphql-tag 定義,傳入 <Query> 執行獲取數據並傳入 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>
    );
}

查詢語句通過graphql-tag定義,然後傳入<Query>執行。

運行

由於本地調試,client和server分別運行在不同的埠,所以需要先進行跨域處理,使用 cors

// server.js
const cors = require('cors');
app.use(cors());

效果

好了,大功告成,我們來看一下效果:

結語

今天就主要介紹GraphQL工程的搭建和GraphQL Query的使用,更多關於GraphQL的內容比如 Mutation下次有空會跟大家逐步講解。

本文靈感來源:Youtube@Traversy Media,感謝

本文Demo Github地址:Github@MudOnTire

本文Demo線上展示:Heroku@graphql-spacex-launches

最後,推薦大家使用Fundebug,一款很好用的BUG監控工具~

關於Fundebug

Fundebug專註於JavaScript、微信小程式、微信小游戲、支付寶小程式、React Native、Node.js和Java線上應用實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了10億+錯誤事件,付費客戶有陽光保險、核桃編程、荔枝FM、掌門1對1、微脈、青團社等眾多品牌企業。歡迎大家免費試用!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在人人手裡都有手機都能上網。在這樣一個信息傳播迅速的時代,怎麼樣讓別人足不出戶就能知道你的企業。 企業的建站是商戶之間網路的橋梁,我們可以通過上海網站建設公司創建一個電子商務的平臺為自己公司做一個網頁版的宣傳。 網站的標識,其目的市場可是一個年齡組或特定的連接鏈,因此採用一個高端大氣又趣味十足的能吸 ...
  • 預編譯四部曲 1.創建AO對象 2.找形參和變數聲明,將變數和形參名作為AO屬性名,值為undefined 3.將實參和形參統一 4.在函數體裡面找函數聲明,值賦予函數體 function fn(a){ console.log(a) //function a(){} var a = 123; con ...
  • description jQuery,顧名思義,也就是JavaScript和Query(查詢),即輔助JavaScript開發的庫。jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計 ...
  • 一 函數 1、字元串函數 s.tolowerCase( ); -- 變小寫 s.toupperCase( ); -- 變大寫 s.substr( 2 , 8 ); -- 截取 從索引2開始截取,截取8個字元長度 s.split( ); -- 指定字元分割,返回一個數組。 括弧里放一個字元,按照這個字 ...
  • 第一種:瀏覽器支持的轉換方式(Firefox,chrome,opera,safari,ie)等瀏覽器: JSON.parse(jsonstr); //可以將json字元串轉換成json對象 JSON.stringify(jsonobj); //可以將json對象轉換成json對符串   第 ...
  • 比如上面這個頁面, 分為三層:divOne是第外層,divTwo中間層,hr_three是最裡層; 他們都有各自的click事件,最裡層a標簽還有href屬性。 運行頁面,點擊“點擊我”,會依次彈出:我是最裡層 >我是中間層 >我是最外層 >然後再鏈接到百度. 這就是事件冒泡,本來我只點擊ID為hr ...
  • 前言 最近在做後臺管理項目,採用的 "vue element admin" ,上傳圖片是一個很常用的功能,也遇到了很多問題,剛好趁此機會做一些總結。 初步總結下會提到的問題,目錄如下: 1. el upload 自定義上傳方法 2. 圖片上傳到七牛雲 3. 圖片壓縮後再上傳(壓縮使用 "lrz" ) ...
  • transition組件可以給任何元素和組件添加進入/離開過渡,但只能給單個組件實行過渡效果(多個元素可以用transition-group組件,下一節再講),調用該內置組件時,可以傳入如下特性: name 用於自動生成CSS過渡類名 例如:name:'fade'將自動拓展為.fade-enter, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...