GraphQL

---

GraphQL [ɡr?f]

---

### GraphQL是什么? (graph n:圖; 圖表; 曲線圖) 美:[ɡr?f]

>關(guān)于GraphQL是什么,網(wǎng)上一搜一大堆。根據(jù)官網(wǎng)的解釋就是一種用于 API 的查詢語言。

>一看到用于API的查詢語言明刷,我也是一臉懵逼的奸晴。博主你在開玩笑吧?你的翻譯水平不過關(guān)贼涩?API還能查嗎茅逮?API不是后端寫好璃赡,前端調(diào)用的嗎判哥?

的確可以,這就是GraphQL強(qiáng)大的地方碉考。

### 為什么要使用GraphQL?

>在實(shí)際工作中往往會有這種情景出現(xiàn):比如說我需要展示一個商品的列表塌计,可接口卻會把商品的描述,更新時間侯谁,創(chuàng)建者等各種各樣的 (無用的) 信息都一同返回锌仅。

問了后端,原因大概如下:

>* 原來是為了兼容PC端和移動端用同一套接口

>* 或者在整個頁面墙贱,這里需要顯示商品的標(biāo)題热芹,可是別的地方需要顯示商品明細(xì)啊,避免多次請求我就全部返回咯

>* 或者是因?yàn)橛袝r候項(xiàng)目經(jīng)理想要顯示“標(biāo)題+更新時間”惨撇,有時候想要點(diǎn)擊標(biāo)題展開商品明細(xì)等等需求伊脓,所以把商品相關(guān)的信息都一同返回

簡單說就是:

>* 兼容多平臺導(dǎo)致字段冗余

>* 一個頁面需要多次調(diào)用 API 聚合數(shù)據(jù)

>* 需求經(jīng)常改動導(dǎo)致接口很難為單一接口精簡邏輯

有同學(xué)可能會說那也不一定要用GraphQL啊,比方說第一個問題魁衙,不同平臺不同接口不就好了嘛

```

http://api.xxx.com/web/getGameInfo/:gameID

http://api.xxx.com/app/getGameInfo/:gameID

http://api.xxx.com/mobile/getGameInfo/:gameID

```

或者加個參數(shù)也行

```

http://api.xxx.com/getGameInfo/:gameID?platfrom=web

```

這樣處理的確可以解決問題报腔,但是無疑加大了后端的處理邏輯。你真的不怕后端程序員打你剖淀?

這個時候我們會想纯蛾,接口能不能不寫死,把靜態(tài)變成動態(tài)纵隔?

### GraphQL嘗嘗鮮——(GraphQL簡單例子)

下面是用GraphQL.js和express-graphql搭建一個的普通GraphQL查詢(query)的例子翻诉,包括講解GraphQL的部分類型和參數(shù),已經(jīng)掌握了的同學(xué)可以跳過捌刮。

> 1.先跑個hello world

>* 1.新建一個graphql文件夾米丘,然后在該目錄下打開終端,執(zhí)行npm init --y初始化一個packjson文件糊啡。

>* 2.安裝依賴包:npm install --save -D express express-graphql graphql

>* 3.新建schema.js文件,填上下面的代碼

>1.hello world

>* 先簡單講解一下代碼:

```typescript

const queryObj = new GraphQLObjectType({

? ? name: 'myFirstQuery',

? ? description: 'a hello world demo',

? ? fields: {}

});

```

GraphQLObjectType是GraphQL.js定義的對象類型吁津,包括name、description 和fields三個屬性,其中name和description 是非必填的徊件。fields是解析函數(shù)卖擅,在這里可以理解為查詢方法

```typescript

hello: {

? ? name: 'a hello world query',

? ? description: 'a hello world demo',

? ? type: GraphQLString,

? ? args: {

? ? ? ? name: {? // 這里定義參數(shù),包括參數(shù)類型和默認(rèn)值

? ? ? ? ? ? type: GraphQLString,

? ? ? ? ? ? defaultValue: 'Brian'

? ? ? ? }

? ? },

? ? resolve(parentValue, args, request) { // 這里演示如何獲取參數(shù)典尾,以及處理

? ? ? ? return 'hello world ' + args.name + '!';

? ? }

}

```

對于每個fields役拴,又有name,description钾埂,type河闰,resolve參數(shù)科平,這里的type可以理解為hello方法返回的數(shù)據(jù)類型,resolve就是具體的處理方法姜性。

說到這里有些同學(xué)可能還不滿足瞪慧,如果我想每次查詢都想帶上一個參數(shù)該怎么辦,如果我想查詢結(jié)果有多條數(shù)據(jù)又怎么處理部念?

schema.js文件弃酌,來一個加強(qiáng)版的查詢(當(dāng)然,你可以整理一下代碼儡炼,我這樣寫是為了方便閱讀)

```typescript

const {

? ? ? GraphQLSchema,

? ? ? GraphQLObjectType,

? ? ? GraphQLString,

? ? ? GraphQLInt,

? ? ? GraphQLBoolean

? ? } = require('graphql');

const queryObj = new GraphQLObjectType({

? ? name: 'myFirstQuery',

? ? description: 'a hello world demo',

? ? fields: {

? ? ? ? hello: {

? ? ? ? ? ? name: 'a hello world query',

? ? ? ? ? ? description: 'a hello world demo',

? ? ? ? ? ? type: GraphQLString,

? ? ? ? ? ? args: {

? ? ? ? ? ? ? ? name: {? // 這里定義參數(shù)妓湘,包括參數(shù)類型和默認(rèn)值

? ? ? ? ? ? ? ? ? ? type: GraphQLString,

? ? ? ? ? ? ? ? ? ? defaultValue: 'Brian'

? ? ? ? ? ? ? ? }

? ? ? ? ? ? },

? ? ? ? ? ? resolve(parentValue, args, request) { // 這里演示如何獲取參數(shù),以及處理

? ? ? ? ? ? ? ? return 'hello world ' + args.name + '!';

? ? ? ? ? ? }

? ? ? ? },

? ? ? ? person: {

? ? ? ? ? ? name: 'personQuery',

? ? ? ? ? ? description: 'query a person',

? ? ? ? ? ? type: new GraphQLObjectType({ // 這里定義查詢結(jié)果包含name,age,sex三個字段乌询,并且都是不同的類型榜贴。

? ? ? ? ? ? ? ? name: 'person',

? ? ? ? ? ? ? ? fields: {

? ? ? ? ? ? ? ? ? name: {

? ? ? ? ? ? ? ? ? ? type: GraphQLString

? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? age: {

? ? ? ? ? ? ? ? ? ? type: GraphQLInt

? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? sex: {

? ? ? ? ? ? ? ? ? ? type: GraphQLBoolean

? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }),

? ? ? ? ? ? args: {

? ? ? ? ? ? ? ? name: {

? ? ? ? ? ? ? ? ? ? type: GraphQLString,

? ? ? ? ? ? ? ? ? ? defaultValue: 'Charming'

? ? ? ? ? ? ? ? }

? ? ? ? ? ? },

? ? ? ? ? ? resolve(parentValue, args, request) {

? ? ? ? ? ? ? ? return {

? ? ? ? ? ? ? ? ? ? name: args.name,

? ? ? ? ? ? ? ? ? ? age: args.name.length,

? ? ? ? ? ? ? ? ? ? sex: Math.random() > 0.5

? ? ? ? ? ? ? ? };

? ? ? ? ? ? }

? ? ? ? }

? ? }

});

module.exports = new GraphQLSchema({

? query: queryObj

});

```

打開http://localhost:8000,在左側(cè)輸入

```typescript

{

? hello(name:"charming"),

? person(name:"charming"){

? ? name,

? ? sex,

? ? age

? }

}

```

右側(cè)就會顯示出:

![示意圖](./images/20180904175443716.png)

你可以在左側(cè)僅輸入person方法的sex和age兩個字段楣责,這樣就會只返回sex和age的信息竣灌。動手試一試吧!

```typescript

{

? person(name:"charming"){

? ? sex,

? ? age

? }

}

```

當(dāng)然,結(jié)果的順序也是按照你輸入的順序排序的秆麸。

定制化的數(shù)據(jù)初嘹,完全根據(jù)你查什么返回什么結(jié)果。這就是GraphQL被稱作API查詢語言的原因沮趣。

> GraphQL是應(yīng)用層查詢語言屯烦,它有自己的數(shù)據(jù)類型,用來描述數(shù)據(jù)房铭,比如標(biāo)量類型驻龟、集合類型、Object類型缸匪、枚舉等翁狐,甚至有接口類型。而GraphQL服務(wù)端不依賴任何語言凌蔬,我只是從概念上來了解其數(shù)據(jù)類型露懒。

### 標(biāo)量類型(Scala)

> 標(biāo)量類型是不能包含子字段,主要有如下類型:

> * Int: 有符號的32位整型

> * Float: 有符號的雙精度浮點(diǎn)型

> * String: UTF‐8字符序列

> * Boolean: 布爾型

> * ID: 常用于獲取數(shù)據(jù)的唯一標(biāo)志砂心,或緩存的鍵值懈词,它也會被序列化為String,但可讀性差辩诞。

> 以上的類型是GraphQL規(guī)范的基本類型坎弯,每個規(guī)范的實(shí)現(xiàn)也可以有自定以標(biāo)量,如 scala Date ,但它必須能夠>序列和反序列化抠忘,至于如何定于取決于具體的規(guī)范實(shí)現(xiàn)撩炊。

1、枚舉(Enum)

枚舉類型是標(biāo)量類型的變體褐桌,不僅適用于可驗(yàn)證性衰抑,還提高了維護(hù)性,它同樣被序列化為String荧嵌。定義形如

```typescript

enum Unit {

? MM

? mm

}

```

MM代表米做單位呛踊,mm代碼毫米做單位。

2啦撮、對象(Ojbect)

> 組成Schema最常用的是對象類型,它包含各種字段谭网,定義如:

```typescript

type User{

  name: String

  sex: String

  intro: String

}

```

以上定義了一個User對象,包含name(名字)赃春、sex(性別)愉择、intro(介紹)屬性字段,而這些屬性字段都是標(biāo)量String類型织中,當(dāng)然屬性也可以是對象類型锥涕。

3、集合(List)

> GraphQL規(guī)范中的集合只有List一種狭吼,它是有序的用 [] 表示层坠,如

```typescript

type User{

? name: String

? sex: String

? intro: String

? skills: [String]

}

```

skills(技能)就是一個list集合,其實(shí)更像是一個數(shù)組刁笙。

4破花、非空/Null(Non-Null)

> 在類型后使用 ! 聲明 非空/Null,如

```typescript

type Query {

? user(id:Int!):User

}

type User{

? name: String!

? sex: String

? intro: String

? skills: [String]!

}

```

> 在類型后使用 ! 聲明 非空/Null疲吸,如? (:8001)

```typescript

query{

? user {

? ? name

? ? sex

? ? intro

? }

}

```

> 則會反饋異常?

```typescript

{

? "errors": [

? ? {

? ? ? "message": "Field \"user\" argument \"id\" of type \"Int!\" is required but not provided.",

? ? ? "locations": [

? ? ? ? {

? ? ? ? ? "line": 2,

? ? ? ? ? "column": 3

? ? ? ? }

? ? ? ]

? ? }

? ]

}

```

> 而實(shí)體類型User的name為非null座每,一但服務(wù)端返回的數(shù)據(jù)name為null,則反饋為

```typescript

{

? "data": {

? ? "user": null

? }

}

```

> 然而需要注意區(qū)別 skills: [String]! 與 skills: [String!] 摘悴,前者是集合不能為null峭梳,后者是集合元素不能為null。

5蹂喻、模式(Schema)

> GraphQL的Schema用于生成文檔葱椭、格式定義與校驗(yàn)等,除了自定義的類型如上文中的User叉橱,還有兩個特殊的類型Query(查詢)和Mutation(維護(hù))。如增查改刪(CRUD)者蠕,增改刪屬于后者窃祝,查屬于前者。 (:8001)

```typescript

schema {

? query: Query

? mutation: Mutation

}

```

> 一個Schema可以沒有mutaion踱侣,但必須有query粪小。

6大磺、查詢(Query)

> Query目的是獲取數(shù)據(jù)。格式

7探膊、維護(hù)(Mutation)

> Mutataion是用來維護(hù)數(shù)據(jù)的杠愧,格式和查詢類似

8、參數(shù)(Argument)

> 客戶端的查詢語句中對象和字段都可以傳入?yún)?shù)逞壁,方便精確控制服務(wù)返回結(jié)果流济,查詢語句如 (:8002)

```typescript

{

? user(id:1) {

? ? name

? ? sex

? ? intro

? ? skills

? ? stature(unit:MM)

? }

}

```

> 服務(wù)返回?cái)?shù)據(jù)

```typescript

{

? "data": {

? ? "user": {

? ? ? "name": "James",

? ? ? "sex": "男",

? ? ? "intro": "zhaiqianfeng的英文名",

? ? ? "skills": [

? ? ? ? "Linux",

? ? ? ? "Java",

? ? ? ? "nodeJs",

? ? ? ? "前端"

? ? ? ],

? ? ? "stature": 1.8

? ? }

? }

}

```

> 服務(wù)端是靠resolver來解析實(shí)現(xiàn)的,后文描述腌闯。

9绳瘟、 指令(Directive)

>客戶端可以使用兩種指令skip和include,可以用與字段(field)姿骏、片段(fragment)糖声,格式和含義如下:

>* field/fragment @skip(if: $isTrue) 當(dāng)$isTrue為真(true)時不查詢field或不使用fragment;

>* field/fragment @include(if: $isTrue) 當(dāng)$isTrue為真(true)時查詢field或使用fragment分瘦;

> 而參數(shù)變量是通過query或mutation傳遞的蘸泻;變量形如$withName:Boolean!,以$開頭嘲玫,以類型結(jié)尾悦施,類型必須是標(biāo)量(scalar)、枚舉(enum)或輸入類型(input)趁冈。如query為 (:8005)

```typescript

query(

? $noWithDog:Boolean!,

? $withName:Boolean!,

? $withFish:Boolean!

){

? animals{

? ? name @include(if:$withName)

? ? ... dogQuery @skip(if:$noWithDog)

? ? ... on Fish @include(if:$withFish){

? ? ? tailColor

? ? }

? }

}

fragment dogQuery on Dog{

? legs

}

```

在query定義中分別定義了$noWithDog(是否帶著狗狗)歼争、$withName(是否帶著Name)、$withFish(是否帶著魚兒)變量渗勘,傳入的參數(shù)變量為

```typescript

{

? "noWithDog": true,

? "withName": true,

? "withFish": true

}

```

查詢的結(jié)果如

```typescript

{

? "data": {

? ? "animals": [

? ? ? {

? ? ? ? "name": "dog"

? ? ? },

? ? ? {

? ? ? ? "name": "fish",

? ? ? ? "tailColor": "red"

? ? ? }

? ? ]

? }

}

```

10沐绒、輸入(Input)

>上面的參數(shù)(Argument)我們使用是標(biāo)量,但當(dāng)使用Mutation來更新數(shù)據(jù)時旺坠,你可能更喜歡傳入一個復(fù)雜的實(shí)體Object乔遮,GraphQL使用input關(guān)鍵字來到定義輸入類型,不直接用Object是為了避開循環(huán)引用取刃、接口或聯(lián)合等一些不可控的麻煩蹋肮,特別是input類型不能像Object那樣帶參數(shù)的。如

```typescript

input UserInput {

? name: String!

? sex: String

? intro: String

? skills: [String]!

}

```

> 定義了一個輸入類型UserInput璧疗,字段有name坯辩、sex、intro和skills.

11崩侠、接口(Interface)

> 類似其他語言漆魔,GraphQL也有接口的概念,方便查詢時返回統(tǒng)一類型,接口是抽象的數(shù)據(jù)類型改抡,因此只有接口的實(shí)現(xiàn)才有意義矢炼,如

```typescript

interface Animal{

  name: String!

}

type Dog implements Animal{

  name: String!

  legs: Int!

}

type Fish implements Animal{

  name: String!

  tailColor: String!

}

```

> 上面的接口Animal有兩個實(shí)現(xiàn):Dog和Fish,它們都有公共字段name阿纤。服務(wù)端的查詢Schema可以是類似如下的定義

```typescript

type Query {

? animals:[Animal]!

}

```

> 而客戶端的查詢需要使用下面的Fragment句灌,稍后展示。

12欠拾、聯(lián)合(Union)

> 聯(lián)合查詢胰锌,類似接口式的組合,但不要求有公共字段清蚀,使用union關(guān)鍵字來定義匕荸,如

```typescript

type Dog{

  chinaName: String!

  legs: Int!

}

type Fish{

  englishName: String!

  tailColor: String!

}

union Animal = Dog | Fish

```

> 則Animal可以是Dog也可以是Fish,服務(wù)端定義查詢可以和上面的接口相同枷邪,客戶端查詢也需要使用Fragment榛搔,稍后展示。

13东揣、 片段(Fragment)

> Fragment分為內(nèi)聯(lián)和外聯(lián)践惑,兩種都是用于選擇主體,而后者還可以共用代碼嘶卧。如上面的接口示例尔觉,Dog和Fish都是接口Animal的實(shí)現(xiàn),有接口的公共字段name芥吟,簡單的內(nèi)聯(lián) (:8003)

```typescript

{

? animals{

? ? name

? ? ... on Dog{

? ? ? legs

? ? }

? ? ... on Fish{

? ? ? tailColor

? ? }

? }

? animalSearch(text:"dog"){

? ? name

? ? ... on Dog{

? ? ? legs

? ? }

? ? ... on Fish{

? ? ? tailColor

? ? }

? }

}

```

> 如果是Dog則查詢legs字段侦铜,如果是Fish則查詢tailColor字段,這種內(nèi)聯(lián)如果單個查詢則比較方便钟鸵,但多個查詢則使用外聯(lián)更簡潔钉稍,如下

```typescript

{

? animals{

? ? ... animalName

? ? ... dogLegs

? ? ... fishTail

? }

? animalSearch(text:"dog"){

? ? ... animalName

? ? ... dogLegs

? ? ... fishTail

? }

}

fragment animalName on Animal {

? name

}

fragment dogLegs on Dog{

? legs

}

fragment fishTail on Fish{

? tailColor

}

```

> 在聯(lián)合(union)查詢,因?yàn)闆]有公共字段棺耍,使用fragment示例如下 (:8004)

```typescript

{

? animals{

? ? ... on Dog{

? ? ? chinaName

? ? ? legs

? ? }

? ? ... on Fish{

? ? ? englishName

? ? ? tailColor

? ? }

? }

}

```

14贡未、別名(Alias)

> GraphQL支持別名命名,這對于查詢多個雷同的結(jié)果非常有用蒙袍,格式為 aliasName: orginName 如 (:8002)

```typescript

{

? james:user(id:1) {

? ? name

? ? sex

? ? intro

? ? skills

? ? MM:stature(unit:MM)

? ? mm:stature(unit:mm)

? }

? zhaiqianfeng:user(id:0) {

? ? name

? ? sex

? ? intro

? ? skills

? ? MM:stature(unit:MM)

? ? mm:stature(unit:mm)

? }

}

```

> 以上分別把id為1俊卤、2的分別給予別名為james、zhaiqianfeng害幅,以米(MM)消恍、毫米(mm)為單位的身高分別給予別名MM、mm以现,服務(wù)端返回的數(shù)據(jù)如

```typescript

{

? "data": {

? ? "james": {

? ? ? "name": "James",

? ? ? "sex": "男",

? ? ? "intro": "zhaiqianfeng的英文名",

? ? ? "skills": [

? ? ? ? "Linux",

? ? ? ? "Java",

? ? ? ? "nodeJs",

? ? ? ? "前端"

? ? ? ],

? ? ? "MM": 1.8,

? ? ? "mm": 180

? ? },

? ? "zhaiqianfeng": {

? ? ? "name": "zhaiqianfeng",

? ? ? "sex": "男",

? ? ? "intro": "博主狠怨,專注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3",

? ? ? "skills": [

? ? ? ? "Linux",

? ? ? ? "Java",

? ? ? ? "nodeJs",

? ? ? ? "前端"

? ? ? ],

? ? ? "MM": 1.8,

? ? ? "mm": 180

? ? }

? }

}

```

15佩抹、 解析(resolve)

> GrapQL API有一個入口點(diǎn),通常稱為“Root”取董,而查詢都是由Root開始,如服務(wù)端定義一個root

```typescript

var root= {

? ? user: {

? ? ? ? name: 'zhaiqianfeng',

? ? ? ? sex: '男',

? ? ? ? intro: '博主无宿,專注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3'

? ? }

};

```

> 在客戶端就可以使用如下查詢語句(:8001)

```typescript

{

? user(id:1) {

? ? name

? ? sex

? ? intro

? }

}

```

> 其實(shí)常用的是使用resolver茵汰,resolver是一個函數(shù),用來處理數(shù)據(jù)孽鸡,GraphQL規(guī)范中resolver的原型是 function(obj,args,context) :

> * obj 代表上一個對象蹂午,一般不常用;

> * args 傳入的參數(shù)彬碱;

> * context 上下文豆胸,比如session、數(shù)據(jù)庫鏈接等巷疼;

> 比如express-graphql的是 function(args,context) 晚胡,省略了第一個obj。因此上例中你可以使用resolver來處理嚼沿,比如:

```typescript

var root= {

? ? user: function(args,context){

? ? ? ? return {

? ? ? ? ? ? name: 'zhaiqianfeng',

? ? ? ? ? ? sex: '男',

? ? ? ? ? ? intro: '博主估盘,專注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3'

? ? ? ? }

? ? }

};

```

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者骡尽。
  • 序言:七十年代末遣妥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子攀细,更是在濱河造成了極大的恐慌箫踩,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谭贪,死亡現(xiàn)場離奇詭異境钟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)故河,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門吱韭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鱼的,你說我怎么就攤上這事理盆。” “怎么了凑阶?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵猿规,是天一觀的道長。 經(jīng)常有香客問我宙橱,道長姨俩,這世上最難降的妖魔是什么蘸拔? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮环葵,結(jié)果婚禮上调窍,老公的妹妹穿的比我還像新娘。我一直安慰自己张遭,他們只是感情好邓萨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著菊卷,像睡著了一般缔恳。 火紅的嫁衣襯著肌膚如雪瘪松。 梳的紋絲不亂的頭發(fā)上瓶逃,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天弯予,我揣著相機(jī)與錄音喳张,去河邊找鬼说庭。 笑死昼捍,一個胖子當(dāng)著我的面吹牛蜂筹,可吹牛的內(nèi)容都是我干的幅慌。 我是一名探鬼主播腰素,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼刃滓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耸弄?” 一聲冷哼從身側(cè)響起咧虎,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎计呈,沒想到半個月后砰诵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捌显,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年茁彭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扶歪。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡理肺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出善镰,到底是詐尸還是另有隱情妹萨,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布炫欺,位于F島的核電站乎完,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏品洛。R本人自食惡果不足惜树姨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一摩桶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧帽揪,春花似錦硝清、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挽霉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間变汪,已是汗流浹背侠坎。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裙盾,地道東北人实胸。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像番官,于是被迫代替她去往敵國和親庐完。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355