内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

創(chuàng)建安全Node.jsGraphQLAPI的快速指南

本文的目標(biāo)是提供關(guān)于如何創(chuàng)建安全的 Node.js GraphQL API 的快速指南?!疽曨l教程推薦:nodejs視頻教程 】

創(chuàng)新互聯(lián)公司專注于埇橋區(qū)網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供埇橋區(qū)營(yíng)銷型網(wǎng)站建設(shè),埇橋區(qū)網(wǎng)站制作、埇橋區(qū)網(wǎng)頁(yè)設(shè)計(jì)、埇橋區(qū)網(wǎng)站官網(wǎng)定制、微信小程序服務(wù),打造埇橋區(qū)網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供埇橋區(qū)網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。

你可能會(huì)想到一些問題:

使用 GraphQL API 的目的是什么?什么是GraphQL API?什么是GraphQL查詢?GraphQL的好處是什么?GraphQL是否優(yōu)于REST?為什么我們使用Node.js?

這些問題都是有意義的,但在回答之前,我們應(yīng)該深入了解當(dāng)前 Web 開發(fā)的狀態(tài):

現(xiàn)在幾乎所有的解決方案都使用了某種應(yīng)用程序編程接口(API)。即使你只用社交網(wǎng)絡(luò)(如Facebook或Instagram),仍然會(huì)用到使用API的前端。如果你感到好奇,你會(huì)發(fā)現(xiàn)幾乎所有在線娛樂服務(wù)都在用不同類型的API,包括Netflix,Spotify和YouTube等。

你會(huì)發(fā)現(xiàn)幾乎在每種情況下都會(huì)有一個(gè)不需要你去詳細(xì)了解的API,例如你不需要知道它們是怎樣構(gòu)建的,并且不需要使用與他們相同的技術(shù)就能夠?qū)⑵浼傻侥阕约旱南到y(tǒng)中。API允許你提供一種可以在服務(wù)器和客戶端通信之間進(jìn)行通用標(biāo)準(zhǔn)通信的方式,而不必依賴于特定的技術(shù)棧。

通過結(jié)構(gòu)良好的API,可以擁有可靠、可維護(hù)且可擴(kuò)展的API,可以為多種客戶端和前端應(yīng)用提供服務(wù)。

什么是 GraphQL API?

GraphQL 是一種 API 所使用的查詢語(yǔ)言,由Facebook開發(fā)并用于其內(nèi)部項(xiàng)目,并于2015年公開發(fā)布。它支持讀取、寫入和實(shí)時(shí)更新等操作。同時(shí)它也是開源的,通常會(huì)與REST和其他架構(gòu)放在一起進(jìn)行比較。簡(jiǎn)而言之,它基于:

GraphQL查詢 —— 允許客戶端進(jìn)行讀取和控制接收數(shù)據(jù)的方式。GraphQL 修改 —— 描述怎樣在服務(wù)器上寫入數(shù)據(jù)。關(guān)于怎樣將數(shù)據(jù)寫入系統(tǒng)的GraphQL約定。

雖然本文應(yīng)該展示一個(gè)關(guān)于如何構(gòu)建和使用GraphQL API的簡(jiǎn)單但真實(shí)的場(chǎng)景,但我們不會(huì)去詳細(xì)介紹GraphQL。因?yàn)镚raphQL團(tuán)隊(duì)提供了全面的文檔,并在Introduction to GraphQL中列出了幾個(gè)實(shí)踐。

什么是GraphQL查詢?

如上所述,查詢是客戶端從API讀取和操作數(shù)據(jù)的一種方式。你可以傳遞對(duì)象的類型,并選擇要接收的字段類型。下面是一個(gè)簡(jiǎn)單的查詢:

query{
  users{
    firstName,
    lastName
  }
}

我們嘗試從用戶庫(kù)中查詢所有用戶,但只接收firstNamelastName。此查詢的結(jié)果將類似于:

{
  "data": {
    "users": [
      {
        "firstName": "Marcos",
        "lastName": "Silva"
      },
      {
        "firstName": "Paulo",
        "lastName": "Silva"
      }
    ]
  }
}

客戶端的使用非常簡(jiǎn)單。

使用GraphQL API的目的是什么?

創(chuàng)建API的目的是使自己的軟件具有可以被其他外部服務(wù)集成的能力。即使你的程序被單個(gè)前端程序所使用,也可以將此前端視為外部服務(wù),為此,當(dāng)通過API為兩者之間提供通信時(shí),你能夠在不同的項(xiàng)目中工作。

如果你在一個(gè)大型團(tuán)隊(duì)中工作,可以將其拆分為創(chuàng)建前端和后端團(tuán)隊(duì),從而允許他們使用相同的技術(shù),并使他們的工作更輕松。

在本文中,我們將重點(diǎn)介紹怎樣構(gòu)建使用GraphQL API的框架。

GraphQL比REST更好嗎?

GraphQL是一種適合多種情況的方法。 REST是一種體系結(jié)構(gòu)方法。如今,有大量的文章可以解釋為什么一個(gè)比另一個(gè)好,或者為什么你應(yīng)該只使用REST而不是GraphQL。另外你可以通過多種方式在內(nèi)部使用GraphQL,并將API的端點(diǎn)維護(hù)為基于REST的架構(gòu)。

你應(yīng)該做的是了解每種方法的好處,分析自己正在創(chuàng)建的解決方案,評(píng)估你的團(tuán)隊(duì)使用解決方案的舒適程度,并評(píng)估你是否能夠指導(dǎo)你的團(tuán)隊(duì)快速掌握這些技術(shù)。

本文更偏重于實(shí)用指南,而不是GraphQL和REST的主觀比較。如果你想查看這兩者的詳細(xì)比較,我建議你查看我們的另一篇文章,為什么GraphQL是API的未來(lái)。

在今天的文章中,我們將專注于怎樣用Node.js創(chuàng)建GraphQL API。

為什么要使用Node.js?

GraphQL有好幾個(gè)不同的支持庫(kù)可供使用。出于本文的目的,我們決定使用Node.js環(huán)境下的庫(kù),因?yàn)樗膽?yīng)用非常廣泛,并且Node.js允許開發(fā)人員使用他們熟悉的前端語(yǔ)法進(jìn)行服務(wù)器端開發(fā)。

掌握GraphQL

我們將為自己的 GraphQL API 設(shè)計(jì)一個(gè)構(gòu)思的框架,在開始之前,你需要了解Node.js和Express的基礎(chǔ)知識(shí)。這個(gè)GraphQL示例項(xiàng)目的源代碼可以在這里找到(https://github.com/makinhs/no...)。

我們將會(huì)處理兩種類型的資源:

Users ,處理基本的CRUD。Products, 我們對(duì)它的介紹會(huì)詳細(xì)一點(diǎn),以展示GraphQL更多的功能。

Users 包含以下字段:

idfirstnamelastnameemailpasswordpermissionLevel

Products 包含以下字段:

idnamedescriptionprice

至于編碼標(biāo)準(zhǔn),我們將在這個(gè)項(xiàng)目中使用TypeScript。

讓我們開始編碼!

首先,要確保安裝了最新的Node.js版本。在本文發(fā)布時(shí),在Nodejs.org上當(dāng)前版本為10.15.3。

初始化項(xiàng)目

讓我們創(chuàng)建一個(gè)名為node-graphql的新文件夾,并在終端或Git CLI控制臺(tái)下使用以下命令:npm init。

配置依賴項(xiàng)和TypeScript

為了節(jié)約時(shí)間,在我們的Git存儲(chǔ)庫(kù)中找到以下代碼去替換你的package.json應(yīng)該包含的依賴項(xiàng):

{
  "name": "node-graphql",
  "version": "1.0.0",
  "description": "",
  "main": "dist/index.js",
  "scripts": {
    "tsc": "tsc",
    "start": "npm run tsc && node ./build/app.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/express": "^4.16.1",
    "@types/express-graphql": "^0.6.2",
    "@types/graphql": "^14.0.7",
    "express": "^4.16.4",
    "express-graphql": "^0.7.1",
    "graphql": "^14.1.1",
    "graphql-tools": "^4.0.4"
  },
  "devDependencies": {
    "tslint": "^5.14.0",
    "typescript": "^3.3.4000"
  }
}

更新package.json后,在終端中執(zhí)行:npm install

接著是配置我們的TypeScript模式。在根文件夾中創(chuàng)建一個(gè)名為tsconfig.json的文件,其中包含以下內(nèi)容:

{
  "compilerOptions": {
    "target": "ES2016",
    "module": "commonjs",
    "outDir": "./build",
    "strict": true,
    "esModuleInterop": true
  }
}

這個(gè)配置的代碼邏輯將會(huì)出現(xiàn)在app文件夾中。在那里我們可以創(chuàng)建一個(gè)app.ts文件,在里面添加以下代碼用于基本測(cè)試:

console.log('Hello Graphql Node API tutorial');

通過前面的配置,現(xiàn)在我們可以運(yùn)行 npm start進(jìn)行構(gòu)建和測(cè)試了。在終端控制臺(tái)中,你應(yīng)該能夠看到輸出的字符串“Hello Graphql Node API tutorial”。在后臺(tái)場(chǎng)景中,我們的配置會(huì)將 TypeScript 代碼編譯為純 JavaScript,然后在build文件夾中執(zhí)行構(gòu)建。

現(xiàn)在為GraphQL API配置一個(gè)基本框架。為了開始我們的項(xiàng)目,將添加三個(gè)基本的導(dǎo)入:

ExpressExpress-graphqlGraphql-tools

把它們放在一起:

import express from 'express';
import graphqlHTTP from 'express-graphql';
import {makeExecutableSchema} from 'graphql-tools';

現(xiàn)在應(yīng)該能夠開始編碼了。下一步是在Express中處理我們的程序和基本的GraphQL配置,例如:

import express from 'express';
import graphqlHTTP from 'express-graphql';
import {makeExecutableSchema} from 'graphql-tools';

const app: express.Application = express();
const port = 3000;


let typeDefs: any = [`
  type Query {
    hello: String
  }
     
  type Mutation {
    hello(message: String) : String
  }
`];

let helloMessage: String = 'World!';

let resolvers = {
    Query: {
        hello: () => helloMessage
    },
    Mutation: {
        hello: (_: any, helloData: any) => {
            helloMessage = helloData.message;
            return helloMessage;
        }
    }
};


app.use(
    '/graphql',
    graphqlHTTP({
        schema: makeExecutableSchema({typeDefs, resolvers}),
        graphiql: true
    })
);
app.listen(port, () => console.log(`Node Graphql API listening on port ${port}!`));

我們正在做的是:

為Express服務(wù)器啟用端口3000。定義我們想要用作快速示例的查詢和修改。定義查詢和修改的工作方式。

好的,但是typeDefs和resolvers中發(fā)生了什么,它們與查詢和修改的關(guān)系又是怎樣的呢?

typeDefs - 我們可以從查詢和修改中獲得的模式的定義。Resolvers - 在這里我們定義了查詢和修改的功能和行為,而不是想要的字段或參數(shù)。Queries - 我們想要從服務(wù)器讀取的“獲取方式”。Mutations - 我們的請(qǐng)求將會(huì)影響在自己的服務(wù)器上的數(shù)據(jù)。

現(xiàn)在讓我們?cè)俅芜\(yùn)行npm start,看看我們能得到些什么。我們希望該程序運(yùn)行后產(chǎn)生這種效果:Graphql API 偵聽3000端口。

我們現(xiàn)在可以試著通過訪問 http://localhost:3000/graphql 查詢和測(cè)試GraphQL API:

好了,現(xiàn)在可以編寫第一個(gè)自己的查詢了,先定義為“hello”。

請(qǐng)注意,我們?cè)?code>typeDefs中定義它的方式,頁(yè)面可以幫助我們構(gòu)建查詢。

這很好,但我們?cè)鯓硬拍芨淖冎的???dāng)然是mutation!

現(xiàn)在,讓我們看看當(dāng)我們用mutation對(duì)值進(jìn)行改變時(shí)會(huì)發(fā)生什么:

現(xiàn)在我們可以用GraphQL Node.js API進(jìn)行基本的CRUD操作了。接下來(lái)開始使用這些代碼。

Products

對(duì)于Products,我們將使用名為products的模塊。為了是本文不那么啰嗦,我們將用內(nèi)存數(shù)據(jù)庫(kù)進(jìn)行演示。先定義一個(gè)模型和服務(wù)來(lái)管理Products。

我們的模型將基于以下內(nèi)容:

export class Product {
  private id: Number = 0;
  private name: String = '';
  private description: String = '';
  private price: Number = 0;

  constructor(productId: Number,
    productName: String,
    productDescription: String,
    price: Number) {
    this.id = productId;
    this.name = productName;
    this.description = productDescription;
    this.price = price;
  }

}

與GraphQL通信的服務(wù)定義為:

export class ProductsService {

    public products: any = [];

    configTypeDefs() {
        let typeDefs = `
          type Product {
            name: String,
            description: String,
            id: Int,
            price: Int
          } `;
        typeDefs += ` 
          extend type Query {
          products: [Product]
        }
        `;

        typeDefs += `
          extend type Mutation {
            product(name:String, id:Int, description: String, price: Int): Product!
          }`;
        return typeDefs;
    }

    configResolvers(resolvers: any) {
        resolvers.Query.products = () => {
            return this.products;
        };
        resolvers.Mutation.product = (_: any, product: any) => {
            this.products.push(product);
            return product;
        };

    }

}
Users

對(duì)于users,我們將遵循與products模塊相同的結(jié)構(gòu)。我們將為用戶提供模型和服務(wù)。該模型將定義為:

export class User {
    private id: Number = 0;
    private firstName: String = '';
    private lastName: String = '';
    private email: String = '';
    private password: String = '';
    private permissionLevel: Number = 1;

    constructor(id: Number,
                firstName: String,
                lastName: String,
                email: String,
                password: String,
                permissionLevel: Number) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
        this.permissionLevel = permissionLevel;
    }

}

同時(shí),我們的服務(wù)將會(huì)是這樣:

const crypto = require('crypto');

export class UsersService {

    public users: any = [];

    configTypeDefs() {
        let typeDefs = `
          type User {
            firstName: String,
            lastName: String,
            id: Int,
            password: String,
            permissionLevel: Int,
            email: String
          } `;
        typeDefs += ` 
          extend type Query {
          users: [User]
        }
        `;

        typeDefs += `
          extend type Mutation {
            user(firstName:String,
             lastName: String,
             password: String,
             permissionLevel: Int,
             email: String,
             id:Int): User!
          }`;
        return typeDefs;
    }

    configResolvers(resolvers: any) {
        resolvers.Query.users = () => {
            return this.users;
        };
        resolvers.Mutation.user = (_: any, user: any) => {
          let salt = crypto.randomBytes(16).toString('base64');
          let hash = crypto.createHmac('sha512', salt).update(user.password).digest("base64");
          user.password = hash;
          this.users.push(user);
          return user;
        };

    }

}

提醒一下,源代碼可以在 https://github.com/makinhs/no... 找到。

現(xiàn)在運(yùn)行并測(cè)試我們的代碼。運(yùn)行npm start,將在端口3000上運(yùn)行服務(wù)器。我們現(xiàn)在可以通過訪問http://localhost:3000/graphql來(lái)測(cè)試自己的GraphQL

嘗試一個(gè)mutation,將一個(gè)項(xiàng)目添加到我們的product列表中:

為了測(cè)試它是否有效,我們現(xiàn)在使用查詢,但只接收id,nameprice

query{
  products{
    id,
    name,
    price
  }
}

將會(huì)返回:
{
  "data": {
    "products": [
          {
        "id": 100,
        "name": "My amazing product",
        "price": 400
      }
    ]
  }
}

很好,按照預(yù)期工作了?,F(xiàn)在可以根據(jù)需要獲取字段了。你可以試著添加一些描述:

query{
  products{
    id,
    name,
    description,
    price
  }
}

現(xiàn)在我們可以對(duì)product進(jìn)行描述。接下來(lái)試試user吧。

mutation{
  user(id:200,
  firstName:"Marcos",
  lastName:"Silva",
  password:"amaz1ingP4ss",
  permissionLevel:9,
  email:"marcos.henrique@toptal.com") {
    id
  }
}

查詢?nèi)缦拢?/p>

query{
  users{
    id,
    firstName,
    lastName,
    password,
    email
  }
}

返回內(nèi)容如下:

{
"data": {
  "users": [
    {
     "id": 200,
     "firstName": "Marcos",
     "lastName": "Silva",
     "password": "kpj6Mq0tGChGbZ+BT9Nw6RMCLReZEPPyBCaUS3X23lZwCCp1Ogb94/
                           oqJlya0xOBdgEbUwqRSuZRjZGhCzLdeQ==",
     "email": "marcos.henrique@toptal.com"
     }
   ]
}
}

到此為止,我們的GraphQL骨架完成!雖然離實(shí)現(xiàn)一個(gè)有用的、功能齊全的API還需要很多步驟,但現(xiàn)在已經(jīng)設(shè)置好了基本的核心功能。

總結(jié)和最后的想法

讓我們回顧一下本文的內(nèi)容:

在Node.js下可以通過Express和GraphQL庫(kù)來(lái)構(gòu)建GraphQL API;基本的GraphQL使用;查詢和修改的基本用法;為項(xiàng)目創(chuàng)建模塊的基本方法;測(cè)試我們的GraphQL API;

為了集中精力關(guān)注GraphQL API本身,我們忽略了幾個(gè)重要的步驟,可簡(jiǎn)要總結(jié)如下:

新項(xiàng)目的驗(yàn)證;使用通用的錯(cuò)誤服務(wù)正確處理異常;驗(yàn)證用戶可以在每個(gè)請(qǐng)求中使用的字段;添加JWT攔截器以保護(hù)API;使用更有效的方法處理密碼哈希;添加單元和集成測(cè)試;

請(qǐng)記住,我們?cè)贕it (https://github.com/makinhs/node-graphql-tutorial)上有完整的源代碼??梢噪S意使用、fork、提問、pull 并運(yùn)行它!請(qǐng)注意,本文中提出的所有標(biāo)準(zhǔn)和建議并不是一成不變的。

這只是設(shè)計(jì)GraphQL API的眾多方法之一。此外,請(qǐng)務(wù)必更詳細(xì)地閱讀和探索GraphQL文檔,以了解它提供的內(nèi)容以及怎樣使你的API更好。

英文地址原文:https://www.toptal.com/graphql/graphql-nodejs-api

更多編程相關(guān)知識(shí),可訪問:編程教程??!

分享題目:創(chuàng)建安全Node.jsGraphQLAPI的快速指南
瀏覽地址:http://m.rwnh.cn/article18/cjhidp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、網(wǎng)站建設(shè)、軟件開發(fā)、網(wǎng)頁(yè)設(shè)計(jì)公司、自適應(yīng)網(wǎng)站微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)
济阳县| 五台县| 静海县| 嵊泗县| 醴陵市| 平乡县| 定兴县| 奇台县| 柳州市| 高青县| 昔阳县| 大安市| 佛学| 盘山县| 三明市| 东丽区| 布拖县| 巨野县| 大方县| 台北市| 琼海市| 呼玛县| 武胜县| 四川省| 靖州| 丰城市| 海宁市| 惠州市| 镇康县| 寻乌县| 哈尔滨市| 余庆县| 衡山县| 寿阳县| 云霄县| 奉新县| 安塞县| 社旗县| 工布江达县| 疏附县| 句容市|