GraphQL 是一種用於 API 的查詢語言,是由 Facebook 開源的一種用於提供數據查詢服務的抽象框架。在服務端 API 開發中,不少時候定義一個接口返回的數據相對固定,所以要得到更多信息或者只想獲得某部分信息時,基於 RESTful API 的接口就顯得不那麼靈活。而 GraphQL 對 API 中的數據提供了一套易於理解的完整描述,使得客戶端可以準確地得到它須要的數據,並且沒有任何冗餘,也讓 API 更容易地隨着時間推移而演進,還能用於構建強大的開發者工具。 目前,LeetCode 和 GitHub 都藉助 GraphQL 來設計,提供了更大的靈活性,對於想借助 GitHub 來了解 GraphQL 可直接訪問 GraphQL API v4 ,或者參考 GraphQL 實戰:Github V4 API使用。而對於在 LeetCode 上使用 GraphQL 查詢,相對資料少一些,所以在這,我主要以 LeetCode 爲例,來作講解(實際上是由於本身業餘刷題時突發奇想,想寫一個爬蟲。java
若是直接搜索以 Java 語言爲載體的 GraphQL 的話,一大部分搜索結果都是介紹使用 graphql-java 來搭建查詢服務,而咱們的目的是利用 GraphQL 來獲取想要的數據,並不是本身搭建一個查詢服務,所以若是一開始就選錯了工具,就會致使後面的方向都是錯誤的。 以 LeetCode 第一題 1.Two Sum 爲例,獲取其後端發送過來的數據。利用 F12 功能調出以下界面,選 Network git
query
的字段,這是咱們要構造的 GraphQL Query 的一個重要信息。
query
的字段相仿(由於有一點須要更改的細節)
Content-Type
是
application/graphql
,Body 中的 GraphQL 構造,參照
Request Payload 中的
query
的字段來構造
query
便可,這也是 GraphQL 的強大之處。好比咱們只想要題目的
content
信息,那麼其
query
則爲
query{question(titleSlug:"two-sum") {content}}
複製代碼
在上邊,已經利用 Postman 查詢到想要的數據了,而如今咱們要作的就是用代碼將上述操做展現出來。這邊,使用 OkHttp 來進行題目信息獲取。github
import okhttp3.*;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import java.io.IOException;
import java.util.Map;
import static java.lang.System.out;
public class Question {
public static void main(String... args) throws IOException {
String questionUrl = "https://leetcode.com/problems/two-sum/description/";
String graphqlUrl = "https://leetcode.com/graphql";
Connection.Response response = Jsoup.connect(questionUrl)
.method(Connection.Method.GET)
.execute();
Map<String,String>cookies = response.cookies();
for (Map.Entry<String,String>entry:cookies.entrySet()){
//out.println(entry.getKey() + ": " + entry.getValue());
}
String csrftoken = response.cookie("csrftoken");
String __cfduid = response.cookie("__cfduid");
OkHttpClient client = new OkHttpClient.Builder()
.followRedirects(false)
.followSslRedirects(false)
.build();
String postBody = "query{\n" +
" question(titleSlug:\"two-sum\") {\n" +
" content\n" +
" }\n" +
"}\n";
Request request = new Request.Builder()
.addHeader("Content-Type","application/graphql")
.addHeader("Referer",questionUrl)
.addHeader("Cookie","__cfduid=" + __cfduid + ";" + "csrftoken=" + csrftoken)
.addHeader("x-csrftoken",csrftoken)
.url(graphqlUrl)
.post(RequestBody.create(MediaType.parse("application/graphql; charset=utf-8"),postBody))
.build();
Response response1 = client.newCall(request).execute();
//out.println(response1.headers());
out.println(response1.body().string());
}
}
複製代碼
執行結果: 後端