精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

GraphQL初體驗,Node.js構建GraphQL API指南

開發 前端
在過去的幾年中,GraphQL[1]已經成為一種非常流行的API規范,該規范專注于使客戶端(無論客戶端是前端還是第三方)的數據獲取更加容易。

[[344231]]

在過去的幾年中,GraphQL[1]已經成為一種非常流行的API規范,該規范專注于使客戶端(無論客戶端是前端還是第三方)的數據獲取更加容易。

目錄:

  • 為什么選擇GraphQL?
  • 定義一個GraphQL schema
  • 設置解析器
  • 運行服務器
  • 性能考量
    • 緩存
    • 授權
  • Schema最佳實踐
  • GraphQL什么時候不合適?
  • 了解更多

在傳統的基于REST的API方法中,客戶端發出請求,而服務器決定響應:

  1. curl https://api.heroku.space/users/1 
  2.  
  3.   "id": 1, 
  4.   "name""Luke"
  5.   "email""luke@heroku.space"
  6.   "addresses": [ 
  7.     { 
  8.     "street""1234 Rodeo Drive"
  9.     "city""Los Angeles"
  10.     "country""USA" 
  11.     } 
  12.   ] 

但是,在GraphQL中,客戶端可以精確地確定其從服務器獲取的數據。例如,客戶端可能只需要用戶名和電子郵件,而不需要任何地址信息:

  1. curl -X POST https://api.heroku.space/graphql -d ' 
  2. query { 
  3.   user(id: 1) { 
  4.     name 
  5.     email 
  6.   } 
  7.  
  8.  
  9.   "data"
  10.     { 
  11.     "name""Luke"
  12.     "email""luke@heroku.space" 
  13.     } 

通過這種新的模式,客戶可以通過縮減響應來滿足他們的需求,從而向服務器進行更高效的查詢。對于單頁應用(SPA)或其他前端重度客戶端應用,可以通過減少有效載荷大小來加快渲染時間。但是,與任何框架或語言一樣,GraphQL也需要權衡取舍。在本文中,我們將探討使用GraphQL作為API的查詢語言的利弊,以及如何開始構建實現。

為什么選擇GraphQL?

與任何技術決策一樣,了解GraphQL為你的項目提供了哪些優勢是很重要的,而不是簡單地因為它是一個流行詞而選擇它。

考慮一個使用API連接到遠程數據庫的SaaS應用程序。你想要呈現用戶的個人資料頁面,你可能需要進行一次API GET 調用,以獲取有關用戶的信息,例如用戶名或電子郵件。然后,你可能需要進行另一個API調用以獲取有關地址的信息,該信息存儲在另一個表中。隨著應用程序的發展,由于其構建方式的原因,你可能需要繼續對不同位置進行更多的API調用。雖然每一個API調用都可以異步完成,但你也必須處理它們的響應,無論是錯誤、網絡超時,甚至暫停頁面渲染,直到收到所有數據。如上所述,這些響應的有效載荷可能超過了渲染你當前頁面的需要,而且每個API調用都有網絡延遲,總的延遲加起來可能很可觀。

使用GraphQL,你無需進行多個API調用(例如 GET /user/:id 和 GET /user/:id/addresses ),而是進行一次API調用并將查詢提交到單個端點:

  1. query { 
  2.   user(id: 1) { 
  3.     name 
  4.     email 
  5.     addresses { 
  6.     street 
  7.     city 
  8.     country 
  9.     } 
  10.   } 

然后,GraphQL僅提供一個端點來查詢所需的所有域邏輯。如果你的應用程序不斷增長,你會發現自己在你的架構中添加了更多的數據存儲——PostgreSQL可能是存儲用戶信息的好地方,而Redis可能是存儲其他種類信息的好地方——對GraphQL端點的一次調用將解決所有這些不同的位置,并以他們所請求的數據響應客戶端。

如果你不確定應用程序的需求以及將來如何存儲數據,則GraphQL在這里也很有用。要修改查詢,你只需添加所需字段的名稱:

  1. addresses { 
  2.       street 
  3. +     apartmentNumber   # new information 
  4.       city 
  5.       country 
  6.     } 

這極大地簡化了隨著時間的推移而發展你的應用程序的過程。

定義一個GraphQL schema

有各種編程語言的GraphQL服務器實現,但在你開始之前,你需要識別你的業務域中的對象,就像任何API一樣。就像REST API可能會使用JSON模式一樣,GraphQL使用SDL或Schema定義語言來定義它的模式,這是一種描述GraphQL API可用的所有對象和字段的冪等方式。SDL條目的一般格式如下:

  1. type $OBJECT_TYPE { 
  2.   $FIELD_NAME($ARGUMENTS): $FIELD_TYPE 

讓我們以前面的例子為基礎,定義一下user和address的條目是什么樣子的。

  1. type User { 
  2.   name:     String 
  3.   email:    String 
  4.   addresses:   [Address] 
  5.  
  6. type Address { 
  7.   street:   String 
  8.   city:     String 
  9.   country:  String 

user 定義了兩個 String 字段,分別是 name 和 email ,它還包括一個稱為 addresses 的字段,它是 Addresses 對象的數組。Addresses 還定義了它自己的幾個字段。(順便說一下,GraphQL模式不僅有對象,字段和標量類型,還有更多,你也可以合并接口,聯合和參數,以構建更復雜的模型,但本文中不會介紹。)

我們還需要定義一個類型,這是我們GraphQL API的入口點。你還記得,前面我們說過,GraphQL查詢是這樣的:

  1. query { 
  2.   user(id: 1) { 
  3.     name 
  4.     email 
  5.   } 

該 query 字段屬于一種特殊的保留類型,稱為 Query ,這指定了獲取對象的主要入口點。(還有用于修改對象的 Mutation 類型。)在這里,我們定義了一個 user 字段,該字段返回一個 User 對象,因此我們的架構也需要定義此字段:

  1. type Query { 
  2.   user(id: Int!): User 
  3.  
  4. type User { ... } 
  5. type Address { ... } 

字段中的參數是逗號分隔的列表,格式為 $NAME: $TYPE。! 是GraphQL表示該參數是必需的方式,省略表示它是可選的。

根據你選擇的語言,將此模式合并到服務器中的過程會有所不同,但通常,將信息用作字符串就足夠了。Node.js有 graphql[2] 包來準備GraphQL模式,但我們將使用 graphql-tools[3] 包來代替,因為它提供了一些更多的好處。讓我們導入該軟件包并閱讀我們的類型定義,以為將來的開發做準備:

  1. const fs = require('fs'
  2. const { makeExecutableSchema } = require("graphql-tools"); 
  3.  
  4. let typeDefs = fs.readFileSync("schema.graphql", { 
  5.   encoding: "utf8"
  6.   flag: "r"
  7. }); 

設置解析器

schema設置了構建查詢的方式,但建立schema來定義數據模型只是GraphQL規范的一部分。另一部分涉及實際獲取數據,這是通過使用解析器完成的,解析器是一個返回字段基礎值的函數。

讓我們看一下如何在Node.js中實現解析器。我們的目的是圍繞著解析器如何與模式一起操作來鞏固概念,所以我們不會圍繞著如何設置數據存儲來做太詳細的介紹。在“現實世界”中,我們可能會使用諸如knex[4]之類的東西建立數據庫連接。現在,讓我們設置一些虛擬數據:

  1. const users = { 
  2.   1: { 
  3.     name"Luke"
  4.     email: "luke@heroku.space"
  5.     addresses: [ 
  6.     { 
  7.       street: "1234 Rodeo Drive"
  8.       city: "Los Angeles"
  9.       country: "USA"
  10.     }, 
  11.     ], 
  12.   }, 
  13.   2: { 
  14.     name"Jane"
  15.     email: "jane@heroku.space"
  16.     addresses: [ 
  17.     { 
  18.       street: "1234 Lincoln Place"
  19.       city: "Brooklyn"
  20.       country: "USA"
  21.     }, 
  22.     ], 
  23.   }, 
  24. }; 

Node.js中的GraphQL解析器相當于一個Object,key是要檢索的字段名,value是返回數據的函數。讓我們從初始 user 按id查找的一個簡單示例開始:

  1. const resolvers = { 
  2.   Query: { 
  3.     userfunction (parent, { id }) { 
  4.       // 用戶查找邏輯 
  5.     }, 
  6.   }, 

這個解析器需要兩個參數:一個代表父的對象(在最初的根查詢中,這個對象通常是未使用的),一個包含傳遞給你的字段的參數的JSON對象。并非每個字段都具有參數,但是在這種情況下,我們將擁有參數,因為我們需要通過用戶ID來檢索其用戶。該函數的其余部分很簡單:

  1. const resolvers = { 
  2.   Query: { 
  3.     userfunction (_, { id }) { 
  4.       return users[id]; 
  5.     }, 
  6.   } 

你會注意到,我們沒有明確定義 User 或 Addresses 的解析器,graphql-tools 包足夠智能,可以自動為我們映射這些。如果我們選擇的話,我們可以覆蓋這些,但是現在我們已經定義了我們的類型定義和解析器,我們可以建立我們完整的模式:

  1. const schema = makeExecutableSchema({ typeDefs, resolvers }); 

運行服務器

最后,讓我們來運行這個demo吧!因為我們使用的是Express,所以我們可以使用 express-graphql[5] 包來暴露我們的模式作為端點。該程序包需要兩個參數:schema和根value,它有一個可選參數 graphiql,我們將稍后討論。

使用GraphQL中間件在你喜歡的端口上設置Express服務器,如下所示:

  1. const express = require("express"); 
  2. const express_graphql = require("express-graphql"); 
  3.  
  4. const app = express(); 
  5. app.use( 
  6.   "/graphql"
  7.   express_graphql({ 
  8.     schemaschema
  9.     graphiql: true
  10.   }) 
  11. ); 
  12. app.listen(5000, () => console.log("Express is now live at localhost:5000")); 

將瀏覽器導航到 http://localhost:5000/graphql,你應該會看到一種IDE界面。在左側窗格中,你可以輸入所需的任何有效GraphQL查詢,而在右側你將獲得結果。

這就是 graphiql: true 所提供的:一種方便的方式來測試你的查詢,你可能不想在生產環境中公開它,但是它使測試變得容易得多。

嘗試輸入上面展示的查詢:

  1. query { 
  2.   user(id: 1) { 
  3.     name 
  4.     email 
  5.   } 

要探索GraphQL的類型化功能,請嘗試為ID參數傳遞一個字符串而不是一個整數。

  1. # 這不起作用 
  2. query { 
  3.   user(id: "1") { 
  4.     name 
  5.     email 
  6.   } 

你甚至可以嘗試請求不存在的字段:

  1. # 這不起作用 
  2. query { 
  3.   user(id: 1) { 
  4.     name 
  5.     zodiac 
  6.   } 

只需用schema表達幾行清晰的代碼,就可以在客戶機和服務器之間建立強類型的契約。這樣可以防止你的服務接收虛假數據,并向請求者清楚地表明錯誤。

性能考量

盡管GraphQL為你解決了很多問題,但它并不能解決構建API的所有固有問題。特別是緩存和授權這兩個方面,只是需要一些預案來防止性能問題。GraphQL規范并沒有為實現這兩種方法提供任何指導,這意味著構建它們的責任落在了你身上。

緩存

基于REST的API在緩存時不需要過度關注,因為它們可以構建在web的其他部分使用的現有HTTP頭策略之上。GraphQL不具有這些緩存機制,這會對重復請求造成不必要的處理負擔。考慮以下兩個查詢:

  1. query { 
  2.   user(id: 1) { 
  3.     name 
  4.   } 
  5.  
  6. query { 
  7.   user(id: 1) { 
  8.     email 
  9.   } 

在沒有某種緩存的情況下,只是為了檢索兩個不同的列,會導致兩個數據庫查詢來獲取ID為 1 的 User。實際上,由于GraphQL還允許使用別名,因此以下查詢有效,并且還執行兩次查找:

  1. query { 
  2.   one: user(id: 1) { 
  3.     name 
  4.   } 
  5.   two: user(id: 2) { 
  6.     name 
  7.   } 

第二個示例暴露了如何批處理查詢的問題。為了快速高效,我們希望GraphQL以盡可能少的往返次數訪問相同的數據庫行。

dataloader[6]程序包旨在解決這兩個問題。給定一個ID數組,我們將一次性從數據庫中獲取所有這些ID;同樣,后續對同一ID的調用也將從緩存中獲取該項目。要使用 dataloader 來構建這個,我們需要兩樣東西。首先,我們需要一個函數來加載所有請求的對象。在我們的示例中,看起來像這樣:

  1. const DataLoader = require('dataloader'); 
  2. const batchGetUserById = async (ids) => { 
  3.    // 在現實生活中,這將是數據庫調用 
  4.   return ids.map(id => users[id]); 
  5. }; 
  6. // userLoader現在是我們的“批量加載功能” 
  7. const userLoader = new DataLoader(batchGetUserById); 

這樣可以解決批處理的問題。要加載數據并使用緩存,我們將使用對 load 方法的調用來替換之前的數據查找,并傳入我們的用戶ID:

  1. const resolvers = { 
  2.   Query: { 
  3.     userfunction (_, { id }) { 
  4.       return userLoader.load(id); 
  5.     }, 
  6.   }, 

授權

對于GraphQL來說,授權是一個完全不同的問題。簡而言之,它是識別給定用戶是否有權查看某些數據的過程。我們可以想象一下這樣的場景:經過認證的用戶可以執行查詢來獲取自己的地址信息,但應該無法獲取其他用戶的地址。

為了解決這個問題,我們需要修改解析器函數。除了字段的參數外,解析器還可以訪問它的父節點,以及傳入的特殊上下文值,這些值可以提供有關當前已認證用戶的信息。因為我們知道地址是一個敏感字段,所以我們需要修改我們的代碼,使對用戶的調用不只是返回一個地址列表,而是實際調用一些業務邏輯來驗證請求:

  1. const getAddresses = function(currUser, user) { 
  2.   if (currUser.id == user.id) { 
  3.     return user.addresses 
  4.   } 
  5.  
  6.   return []; 
  7.  
  8. const resolvers = { 
  9.   Query: { 
  10.     userfunction (_, { id }) { 
  11.       return users[id]; 
  12.     }, 
  13.   }, 
  14.   User: { 
  15.     addresses: function (parentObj, {}, context) { 
  16.       return getAddresses(context.currUser, parentObj); 
  17.     }, 
  18.   }, 
  19. }; 

同樣,我們不需要為每個 User 字段顯式定義一個解析程序,只需定義一個我們要修改的解析程序即可。

默認情況下,express-graphql 會將當前的HTTP請求作為上下文的值來傳遞,但在設置服務器時可以更改:

  1. app.use( 
  2.   "/graphql"
  3.   express_graphql({ 
  4.     schemaschema
  5.     graphiql: true
  6.     context: { 
  7.       currUser: user // 當前經過身份驗證的用戶 
  8.     } 
  9.   }) 
  10. ); 

Schema最佳實踐

GraphQL規范中缺少的一個方面是缺乏對版本控制模式的指導。隨著應用程序的成長和變化,它們的API也會隨之變化,很可能需要刪除或修改GraphQL字段和對象。但這個缺點也是積極的:通過仔細設計你的GraphQL schema,你可以避免在更容易實現(也更容易破壞)的REST端點中明顯的陷阱,如命名的不一致和混亂的關系。

此外,你應該盡量將業務邏輯與解析器邏輯分開。你的業務邏輯應該是整個應用程序的單一事實來源。在解析器中執行驗證檢查是很有誘惑力的,但隨著模式的增長,這將成為一種難以維持的策略。

GraphQL什么時候不合適?

GraphQL不能像REST一樣精確地滿足HTTP通信的需求。例如,無論查詢成功與否,GraphQL僅指定一個狀態碼——200 OK。在這個響應中會返回一個特殊的錯誤鍵,供客戶端解析和識別出錯的地方,因此,錯誤處理可能會有些棘手。

 

同樣,GraphQL只是一個規范,它不會自動解決你的應用程序面臨的每個問題。性能問題不會消失,數據庫查詢不會變得更快,總的來說,你需要重新思考關于你的API的一切:授權、日志、監控、緩存。版本化你的GraphQL API也可能是一個挑戰,因為官方規范目前不支持處理中斷的變化,這是構建任何軟件不可避免的一部分。如果你有興趣探索GraphQL,你需要投入一些時間來學習如何將其與你的需求進行最佳整合。

本文轉載自微信公眾號「前端全棧開發者」,可以通過以下二維碼關注。轉載本文請聯系前端全棧開發者公眾號。

 

責任編輯:武曉燕 來源: 前端全棧開發者
相關推薦

2011-11-01 10:30:36

Node.js

2023-01-10 14:11:26

2021-05-07 09:06:55

GraphQLAPI 以太坊

2016-08-05 15:04:33

javascripthtmljs

2011-11-10 08:55:00

Node.js

2022-12-05 07:13:44

2015-03-10 10:59:18

Node.js開發指南基礎介紹

2023-04-18 15:18:10

2021-02-01 15:42:45

Node.jsSQL應用程序

2019-12-09 08:00:00

GraphQLAPI架構

2022-05-06 09:52:17

REST接口API

2019-03-29 16:40:02

Node.js多線程前端

2022-03-08 15:13:34

Fetch APINode.js開發者

2024-01-09 09:09:45

RESTGraphQL

2018-04-23 14:31:02

微服務GraphQLBFF

2022-08-22 07:26:32

Node.js微服務架構

2017-08-18 12:15:35

大數據MySQLGraphQL

2024-06-24 00:20:00

API應用程序接口

2022-09-04 15:54:10

Node.jsAPI技巧

2020-10-27 09:18:19

性能測試查詢
點贊
收藏

51CTO技術棧公眾號

97成人精品视频在线观看| 亚洲精品97久久| 国产在线视频综合| 天天干视频在线观看| 视频一区欧美精品| 精品中文字幕视频| 久久久久久九九九九九| 电影一区二区三区久久免费观看| 三级小视频在线观看| 欧美在线电影| 亚洲高清一二三区| 我要看一级黄色大片| 欧洲性视频在线播放| 中文字幕乱码久久午夜不卡 | 久久伊人成人网| 欧美美乳视频| 亚洲成人久久一区| 在线能看的av网站| 欧美一区国产| 精品成人av一区| 最新视频 - x88av| 国产色a在线| 不卡的av在线播放| 91人人爽人人爽人人精88v| 国产精品久久久久久人| 日韩.com| 亚洲天堂av网| 中文字幕5566| 国产主播性色av福利精品一区| 欧美日韩国产不卡| www.日本xxxx| 性欧美freesex顶级少妇| 一个色综合av| 亚洲欧美一二三| 在线看的av网站| 久久精品网站免费观看| 精品乱码一区| 免费a视频在线观看| 国产精品综合在线视频| 国产精品久久久久91| 久久久久久91亚洲精品中文字幕| 黄色另类av| 欧美疯狂做受xxxx高潮| 国产三级国产精品国产国在线观看| 欧美精品一区二区三区中文字幕| 亚洲精品色婷婷福利天堂| 喷水视频在线观看| 欧美a一欧美| 日韩av在线最新| 国产黑丝一区二区| 欧美绝顶高潮抽搐喷水合集| 亚洲第一精品福利| 午夜视频在线观看国产| 卡通动漫精品一区二区三区| 精品久久久久一区二区国产| 女女调教被c哭捆绑喷水百合| 国内精品视频| 欧美不卡视频一区| 免费在线观看日韩av| 91亚洲精品视频在线观看| 日韩精品中文字幕一区| 国产精品99精品无码视亚| 亚洲第一二区| 亚洲国产精品va在线看黑人动漫| 喷水视频在线观看| 天堂成人娱乐在线视频免费播放网站 | 国产91在线亚洲| 欧美人与禽猛交乱配| 亚洲国产日韩一级| www一区二区www免费| 中文字幕在线看片| 欧美色成人综合| 一起草最新网址| 蜜臀av一区| 亚洲人成在线观看| 三级黄色录像视频| 国产一区清纯| 日本在线观看天堂男亚洲| 自拍偷拍校园春色| 精品一区二区三区免费毛片爱| 91久久精品日日躁夜夜躁国产| 国产亲伦免费视频播放| 成人夜色视频网站在线观看| 久久精品成人一区二区三区蜜臀| 成人在线观看一区| 伊人色综合久久天天| 久久成人免费观看| 韩国理伦片久久电影网| 欧美变态tickling挠脚心| 无码人妻精品一区二区三应用大全 | 三级欧美在线一区| 91久久久亚洲精品| 五月天福利视频| 国产精品欧美经典| 青青在线免费观看| 国产欧美自拍| 亚洲大胆人体视频| 国产精品久久久免费看| 黄色亚洲在线| 国产精品一区二区久久久| 精品国产伦一区二区三区| 99久久精品情趣| 中文字幕一区二区三区在线乱码| 鲁鲁在线中文| 欧美一卡二卡在线观看| 久久久久久九九九九九| 国内一区二区三区| 国产在线精品播放| 男人av在线| 亚洲成av人影院| 免费av不卡在线| 日韩最新在线| 久久6免费高清热精品| 欧美性受xxx黑人xyx性爽| 高清在线成人网| 天天做天天爱天天高潮| 欧美一区国产| 亚洲精品美女在线| 黄色在线观看免费| 精品一区二区在线视频| 色综合久久88色综合天天提莫| av漫画网站在线观看| 欧美一区二区在线播放| 男人舔女人下部高潮全视频| 18成人免费观看视频| 91天堂在线观看| 一级毛片视频在线观看| 一本色道久久加勒比精品 | 女人另类性混交zo| 精品一区二区男人吃奶| 欧美福利小视频| va视频在线观看| 亚洲日本一区二区| 超碰人人草人人| 久久亚洲成人| 国产精品欧美激情| 国产三级在线免费| 在线这里只有精品| 精品成人av一区二区三区| 亚洲精品欧洲| 精品久久久久亚洲| 牛牛精品一区二区| 精品亚洲精品福利线在观看| 日本一区二区网站| 波波电影院一区二区三区| 成人在线免费高清视频| 亚洲一区二区三区日本久久九| 欧美成人高清视频| 亚洲av无码国产综合专区| 亚洲欧美aⅴ...| 中文字幕亚洲日本| 亚洲小说区图片区| 精品国产一区二区三区四区vr | 国产日韩av高清| 欧美日韩在线资源| 8v天堂国产在线一区二区| 熟女av一区二区| 国产福利精品导航| 日韩中文字幕在线免费| 思热99re视热频这里只精品| 日本视频久久久| 91欧美在线视频| 4438x成人网最大色成网站| 日本精品人妻无码77777| 国产成人亚洲精品青草天美| 东北少妇不带套对白| 婷婷综合一区| 国产日韩换脸av一区在线观看| 米奇777四色精品人人爽| 日韩一级完整毛片| 日本少妇做爰全过程毛片| www国产精品av| 成人免费在线观看视频网站| 欧美国产先锋| 久久久综合香蕉尹人综合网| 久久野战av| 久久午夜a级毛片| 日本人妻熟妇久久久久久| 色婷婷精品大视频在线蜜桃视频| 污污视频网站在线免费观看| 国产ts人妖一区二区| 看av免费毛片手机播放| 欧美成人milf| 国产精品麻豆免费版| 欧美xx视频| 欧美丰满少妇xxxxx| 国产在线一二| 精品日韩欧美一区二区| 高潮毛片又色又爽免费 | 日韩在线视频免费观看| 亚洲av色香蕉一区二区三区| 日本久久电影网| 91精品国产高清一区二区三蜜臀| 91香蕉视频黄| 亚洲熟女乱综合一区二区| 日本中文在线一区| 成人黄色片免费| 日韩av专区| 精品国产乱码久久久久软件 | 蜜桃av综合| 欧美人与动牲交xxxxbbbb| 国产成人调教视频在线观看 | 99久久久久国产精品| 精品国产日本| 亚洲精品a区| 国产精品久久91| 在线看片福利| 久久久这里只有精品视频| 欧美性videos| 一区二区三区在线播放欧美| 色综合久久久久久| 欧美一区二区三区婷婷月色| 国产真人无遮挡作爱免费视频| 亚洲午夜av在线| www深夜成人a√在线| 久久丝袜美腿综合| 国产激情视频网站| 国产一区二区不卡在线| 波多野结衣xxxx| 视频一区视频二区中文| 三上悠亚久久精品| 欧美在线1区| 日韩精品最新网址| 五月激情五月婷婷| 国产欧美在线| 老太脱裤让老头玩ⅹxxxx| 综合国产在线| 一级黄色录像免费看| 日韩专区精品| 亚洲欧洲日韩综合二区| 国产99久久精品一区二区300| 国产精品午夜av在线| 一区二区三区四区精品视频| 国产在线精品播放| 欧美91在线|欧美| 国产精品中文字幕在线观看| 欧美大胆性生话| 国产99在线|中文| 日韩免费福利视频| 国产精品av免费在线观看| 亚洲综合在线电影| 国产精品mp4| 视频一区在线免费看| 国产精品一区久久久| 91另类视频| 成人黄色免费网站在线观看| 国产精品4hu.www| 成人黄色免费看| 久久的色偷偷| 痴汉一区二区三区| 卡通动漫国产精品| 欧美极品视频一区二区三区| 国产91精品对白在线播放| 视频一区二区在线观看| 日韩欧美二区| www.黄色网址.com| 亚洲特色特黄| 免费无遮挡无码永久视频| 媚黑女一区二区| 亚洲综合日韩欧美| 国产精品一区二区91| 成人午夜精品无码区| 国产偷国产偷亚洲高清人白洁| 永久免费毛片在线观看| 国产精品久久99| 久久国产精品二区| 欧美日韩免费在线观看| 日韩 国产 欧美| 欧美日韩精品一区二区天天拍小说| 91国产精品一区| 欧美精品一区二区三区蜜桃| 欧美女子与性| 日韩专区在线播放| 俄罗斯一级**毛片在线播放| 97成人在线视频| 日韩成人在线一区| 国产自产在线视频一区| 欧洲激情综合| www.日本三级| 日韩国产在线一| 亚洲精品乱码久久久久久9色| av成人动漫在线观看| 黄大色黄女片18免费| 亚洲在线视频网站| 波多野结衣在线观看一区| 欧美一区二区在线观看| 男人天堂网在线| 欧美另类第一页| 91精品影视| 99久热re在线精品996热视频| 神马久久影院| 水蜜桃在线免费观看| 蘑菇福利视频一区播放| 免费人成视频在线播放| 久久久精品2019中文字幕之3| 午夜精品一区二区三区视频| 欧美日韩中文字幕| 精品国产亚洲AV| 中文字幕视频一区二区在线有码| 国产探花在线观看| 国产精品视频区| 婷婷激情久久| 日本大片免费看| 麻豆成人久久精品二区三区小说| 国产综合内射日韩久| 中文字幕亚洲一区二区va在线| 丰满少妇乱子伦精品看片| 日韩一区二区三区精品视频 | 91色婷婷久久久久合中文| 国内偷拍精品视频| 欧美少妇性性性| 牛牛影视精品影视| 久久免费视频在线观看| 国产精品久久久久久av公交车| 欧美日韩另类综合| 亚洲精品女人| 蜜臀aⅴ国产精品久久久国产老师| 亚洲国产精品ⅴa在线观看| 91精品国产综合久久久蜜臀九色| 欧美一级高清片| 欧洲不卡视频| 国产自产女人91一区在线观看| 视频一区在线观看| 亚洲精品乱码久久久久久自慰| 成人av在线看| 日韩av在线播| 亚洲精品在线一区二区| 日韩特级毛片| 99精品在线直播| 亚洲一级淫片| 特级黄色片视频| 自拍偷拍亚洲激情| 91久久久久久久久久久久| 少妇久久久久久| 欧美成人黄色| 中文字幕99| 韩国欧美国产1区| 亚洲不卡在线播放| 91麻豆精品国产91久久久使用方法 | 天堂av资源在线| 91产国在线观看动作片喷水| 国产精品久久久久av蜜臀| 男人天堂av片| 99视频一区二区| 中文字幕亚洲高清| 亚洲片国产一区一级在线观看| 欧美7777| 亚洲国产一区二区精品视频 | 日本免费中文字幕在线| 国产精品一区二区久久久| 国产精品99久久精品| 免费av不卡在线| 亚洲一区二区在线观看视频| 丰满少妇在线观看bd| 性欧美在线看片a免费观看| 天堂成人娱乐在线视频免费播放网站| 欧美极品欧美精品欧美| 久久综合九色综合久久久精品综合| 亚洲精品中文字幕乱码三区91| 亚洲人成免费电影| 久久国产三级| 亚洲精品国产suv一区88| 成人av免费观看| 国产亚洲欧美在线精品| 中文国产亚洲喷潮| 韩国三级成人在线| 久激情内射婷内射蜜桃| 国产女主播一区| jizz中国少妇| 992tv在线成人免费观看| 国产一区99| 激情久久综合网| 午夜精品福利久久久| 国产精品一区在线看| 亚洲wwwav| 亚洲综合精品| 久久精品在线观看视频| 精品国内片67194| 免费污视频在线一区| 蜜臀av.com| 不卡的av电影| ,亚洲人成毛片在线播放| 久久这里有精品视频| 欧美一性一交| www.51色.com| 色诱亚洲精品久久久久久| 成年人黄视频在线观看| 蜜桃视频成人| 国产成人自拍高清视频在线免费播放| 在线观看亚洲欧美| 久久五月天综合| 精品国产精品| 中国免费黄色片| 欧美日韩一区二区三区不卡| 欧美家庭影院| 一级日韩一区在线观看| 99久久精品免费精品国产| 国产精品丝袜黑色高跟鞋| 庆余年2免费日韩剧观看大牛| 中文字幕一区二区三区乱码图片|