開局兩張圖,內容全靠編~
html
區別分離和半分離的標誌在於Controller
層由不禁前端控制,Controller
在前端手裏,前端手裏握着組裝數據的邏輯,那就是先後端分離!不然就是半分離!前端
那麼,半分離和分離的架構是長下面這樣的
java
ps
:中小型公司慎重,不要玩先後端分離架構!前端工做量賊大!spring
那麼用上了先後端分離架構後,後端的API通常會按照Restful風格來設計!ResultFul推薦每一個URL能操做具體的資源,並且能準確描述服務器對資源的處理動做,一般服務器對資源支持get/post/put/delete/等,用來實現資源的增刪改查。先後端分離的架構下,這些api-url是對接的橋樑,採用ResultFul接口地址含義才更清晰、見名知意。
那麼,在實踐RestFul風格的API的有一個致命的缺陷,是神馬類?嗯,帶着你的疑惑開始本文後端
假設,此時咱們有兩個資源分別是Book
和Author
,這兩個資源對應的ER圖以下
api
相應的API有數組
POST /books
GET /books/{id}
POST /authors
GET /authors/{id}springboot
咱們有一個需求,須要查詢id=1的圖書信息!
那咱們的請求地址是這樣的服務器
GET /books/1restful
返回結果是這樣的
[{ "id": 1, "bookname": Harry Potter, "price": 56.00, "author_id": 2 }]
這時候前端MM拿到這個結果後,傻了眼!這裏怎麼能直接返回author_id
呢,難道直接把author_id
顯示在界面上麼?不可能啊,界面上要顯示的是author_name
才行!
OK,那麼在這種狀況下,有兩種方式能夠解決問題!
(1) 跟後端溝通,讓他增長一個接口
嗯,咱們複習一下什麼是VO對象。
VO(View Object):視圖對象,用於展現層,它的做用是把某個指定頁面(或組件)的全部數據封裝起來。
那可讓後端封裝一個接口,後端幫你把數據拼裝好,提供API以下
GET /bookVOs/1
這樣直接返回的結果就是
[{ "id": 1, "bookname": Harry Potter, "price": 56.00, "author_name": J. K. Rowling }]
固然,由於你這是臨時讓後端加接口,可能會有以下情形產生
OK,回到正題,這樣作的缺點主要有兩個
(2) 本身作適配
這個也很簡單,前端得到結果後,取出author_id: 2
這條記錄,而後再去調用地址
GET /authors/2
獲得結果,而後進行組裝顯示!
固然,這個時候會有以下情形產生(這就是我注孤生的緣由!)
固然,這種作法的缺點也很明顯
ok,經過上面的描述,你們應該能體會到Rest的缺點:REST接口時返回的數據格式、數據類型都是後端預先定義好的,若是返回的數據格式並非調用者所指望的,調用者在處理上比較麻煩!
那麼,有沒有辦法讓前端自定靈活的使用查詢語句,本身想撈什麼數據就撈什麼數據呢?
有的,那就是Graphql!
Graphql其實要這樣理解
Graphql=grap(圖)+query+lanage
是一種基於圖的查詢語言!那麼,這張圖長什麼樣?
OK,首先你要聲明一下,你的圖結構,嗯,用的就是Graphql的語法啦,像下面這樣
type Book { id: Int bookname: String authors: [Author] } type Author { id: Int name: String age: String } type Query { getBook(id: Int): Book } schema { query: Query }
對上面的語句進行一下解釋。這裏一共聲明瞭三個類Book
、Author
、Query
!其實,Book
和Author
你們均可以猜都出來是指啥,須要注意的一點是authors: [Author]
這個地方,用了一個[]
的語法,這表明Author
是一個數組!
惟一須要說明的是,Query
是什麼鬼?
Query
在這兒代表了該類型是這張圖的入口,也就是根節點!咱們的查詢必須從根節點裏的屬性開始!這裏我爲了便於說明,只列了一個屬性,也就是getBook
,該屬性是入口,必須從入口開始查!
那麼,生成的圖是長下面這樣的
這裏還有一個Resolver
的概念,就是說,GragphQL
解析到getBook
方法的時候,方法體內容是啥?是在Resovler
中定義的,我這裏就不貼配置了,感興趣的能夠本身去官網閱讀!
OK,接下來就是第二個問題,怎麼查?
根據上面我說的,只能從根開始,根是getBook
,那語句怎麼寫呢?以下所示
那你想加個字段,顯示做者名字呢?直接像下面這麼寫
採用這種語法結構,後端的數據模型就變成了一張圖,前端能夠定製化本身的輸出結構,同時能夠減小先後端的溝通成本,提升靈活性!
(1)java語言中,對Graphql的支持如何?
在java中,有個jar包爲graphql-java-tools
提供了對Java的支持。
另外,考慮到如今大可能是springboot項目,有大神封裝好了starter包,供大家的springboot項目使用!
只需在項目中引入
<!-- graphql --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-spring-boot-starter</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java-tools</artifactId> <version>4.3.0</version> </dependency>
便可讓你的springboot項目擁有graphql的功能,很是方便!
(2)這樣作不會加劇先後端工做量麼?
說句實在話,摸着良心說,前期確實加劇了先後端的工做量!
對前端而言:須要去了解Graphql
的語法!
對後端而言:不只須要瞭解Graphql
的語法,還須要去編寫Schema
和Resovler
!
因此短時間內,確實增長了工做量!可是從長遠來看,同時下降了先後端的工做量!第一,前端不用瞭解後端的數據結構,GraphQL本身生成可交互式的接口文檔,前端能夠本身測試調用
第二,後端不用在編寫什麼接口文檔,GrapQL自動幫你生成,用起來很是舒心!
本文介紹了Rest的缺點,以及Graphql的基本知識,但願你們有所收穫!