摘要:原文地址使用語(yǔ)法從版本開(kāi)始可以定義多個(gè)語(yǔ)法如果您想要一個(gè)公共的入口,另一個(gè)需要身份驗(yàn)證的入口,那么擁有多個(gè)語(yǔ)法是非常有用的。
原文地址:
readme.md
advanced.md
使用 語(yǔ)法 / Schemas從 1.0 版本開(kāi)始, 可以定義多個(gè)語(yǔ)法, 如果您想要一個(gè)公共的入口,另一個(gè)需要身份驗(yàn)證的入口,那么擁有多個(gè)語(yǔ)法是非常有用的。
您可以在配置中定義多個(gè)語(yǔ)法:
"schema" => "default",
"schemas" => [
"default" => [
"query" => [
//"users" => "AppGraphQLQueryUsersQuery"
],
"mutation" => [
//"updateUserEmail" => "AppGraphQLQueryUpdateUserEmailMutation"
]
],
"secret" => [
"query" => [
//"users" => "AppGraphQLQueryUsersQuery"
],
"mutation" => [
//"updateUserEmail" => "AppGraphQLQueryUpdateUserEmailMutation"
]
]
]
或者可以使用 facade 來(lái)添加語(yǔ)法
GraphQL::addSchema("secret", [
"query" => [
"users" => "AppGraphQLQueryUsersQuery"
],
"mutation" => [
"updateUserEmail" => "AppGraphQLQueryUpdateUserEmailMutation"
]
]);
隨后, 你可以使用 facade 來(lái)創(chuàng)建語(yǔ)法
// Will return the default schema defined by "schema" in the config
$schema = GraphQL::schema();
// Will return the "secret" schema
$schema = GraphQL::schema("secret");
// Will build a new schema
$schema = GraphQL::schema([
"query" => [
//"users" => "AppGraphQLQueryUsersQuery"
],
"mutation" => [
//"updateUserEmail" => "AppGraphQLQueryUpdateUserEmailMutation"
]
]);
你可以通過(guò)指定的語(yǔ)法來(lái)訪問(wèn)
// Default schema
http://homestead.app/graphql?query=query+FetchUsers{users{id,email}}
// Secret schema
http://homestead.app/graphql/secret?query=query+FetchUsers{users{id,email}}
創(chuàng)建查詢(xún)
首先你需要?jiǎng)?chuàng)建一個(gè)類(lèi)型
namespace AppGraphQLType;
use GraphQLTypeDefinitionType;
use FolkloreGraphQLSupportType as GraphQLType;
class UserType extends GraphQLType
{
protected $attributes = [
"name" => "User",
"description" => "A user"
];
/*
* Uncomment following line to make the type input object.
* http://graphql.org/learn/schema/#input-types
*/
// protected $inputObject = true;
public function fields()
{
return [
"id" => [
"type" => Type::nonNull(Type::string()),
"description" => "The id of the user"
],
"email" => [
"type" => Type::string(),
"description" => "The email of user"
]
];
}
// If you want to resolve the field yourself, you can declare a method
// with the following format resolve[FIELD_NAME]Field()
protected function resolveEmailField($root, $args)
{
return strtolower($root->email);
}
}
然后將類(lèi)型添加到 config/graphql.php 文件中
"types" => [
"User" => "AppGraphQLTypeUserType"
]
你也可以使用 GraphQL Facade 來(lái)進(jìn)行添加, 添加到 service provider 中
GraphQL::addType("AppGraphQLTypeUserType", "User");
然后, 你需要定義一個(gè)查詢(xún)并且返回這個(gè)類(lèi)型(或者列表). 你同樣也可以在指定的參數(shù), 這些參數(shù)可以用在 resolve 方法中.
namespace AppGraphQLQuery;
use GraphQL;
use GraphQLTypeDefinitionType;
use FolkloreGraphQLSupportQuery;
use AppUser;
class UsersQuery extends Query
{
protected $attributes = [
"name" => "users"
];
public function type()
{
return Type::listOf(GraphQL::type("User"));
}
public function args()
{
return [
"id" => ["name" => "id", "type" => Type::string()],
"email" => ["name" => "email", "type" => Type::string()]
];
}
public function resolve($root, $args)
{
if (isset($args["id"])) {
return User::where("id" , $args["id"])->get();
} else if(isset($args["email"])) {
return User::where("email", $args["email"])->get();
} else {
return User::all();
}
}
}
添加 query 到 config/graphql.php 文件中
"schemas" => [
"default" => [
"query" => [
"users" => "AppGraphQLQueryUsersQuery"
],
// ...
]
]
這樣就OK了, 你可以使用 /graphql 來(lái)進(jìn)行查詢(xún)了. 嘗試使用 get 請(qǐng)求來(lái)獲取下數(shù)據(jù)
query FetchUsers {
users {
id
email
}
}
或者使用 url 地址來(lái)進(jìn)行請(qǐng)求
http://homestead.app/graphql?query=query+FetchUsers{users{id,email}}
創(chuàng)建修改
更改就是另外一種形式的查詢(xún), 他接受參數(shù)(用來(lái)進(jìn)行更改或者創(chuàng)建使用的)并且返回一個(gè)對(duì)象或者指定的類(lèi)型
例如使用修改來(lái)更新用戶(hù)的密碼, 首先你需要定義 mutation
namespace AppGraphQLMutation;
use GraphQL;
use GraphQLTypeDefinitionType;
use FolkloreGraphQLSupportMutation;
use AppUser;
class UpdateUserPasswordMutation extends Mutation
{
protected $attributes = [
"name" => "updateUserPassword"
];
public function type()
{
return GraphQL::type("User");
}
public function args()
{
return [
"id" => ["name" => "id", "type" => Type::nonNull(Type::string())],
"password" => ["name" => "password", "type" => Type::nonNull(Type::string())]
];
}
public function resolve($root, $args)
{
$user = User::find($args["id"]);
if (!$user) {
return null;
}
$user->password = bcrypt($args["password"]);
$user->save();
return $user;
}
}
就想 resolve 方法. 你使用參數(shù)來(lái)更新你的模型并且返回她.
然后添加 mutation 到 config/graphql.php 文件中
"schema" => [
"default" => [
"mutation" => [
"updateUserPassword" => "AppGraphQLMutationUpdateUserPasswordMutation"
],
// ...
]
]
你可以使用如下的查詢(xún)來(lái)進(jìn)行修改
mutation users {
updateUserPassword(id: "1", password: "newpassword") {
id
email
}
}
url 中可以如下請(qǐng)求
http://homestead.app/graphql?query=mutation+users{updateUserPassword(id: "1", password: "newpassword"){id,email}}
添加修改驗(yàn)證
在修改中增加驗(yàn)證是可以的. 老鐵. 它使用 laravel Validator 來(lái)處理驗(yàn)證并且返回相應(yīng)的參數(shù).
當(dāng)創(chuàng)建 mutation 的時(shí)候, 你可以添加如下方法來(lái)定義驗(yàn)證規(guī)則:
namespace AppGraphQLMutation;
use GraphQL;
use GraphQLTypeDefinitionType;
use FolkloreGraphQLSupportMutation;
use AppUser;
class UpdateUserEmailMutation extends Mutation
{
protected $attributes = [
"name" => "UpdateUserEmail"
];
public function type()
{
return GraphQL::type("User");
}
public function args()
{
return [
"id" => ["name" => "id", "type" => Type::string()],
"email" => ["name" => "email", "type" => Type::string()]
];
}
public function rules()
{
return [
"id" => ["required"],
"email" => ["required", "email"]
];
}
public function resolve($root, $args)
{
$user = User::find($args["id"]);
if (!$user) {
return null;
}
$user->email = $args["email"];
$user->save();
return $user;
}
}
同樣, 你可以在參數(shù)中定義規(guī)則:
class UpdateUserEmailMutation extends Mutation
{
//...
public function args()
{
return [
"id" => [
"name" => "id",
"type" => Type::string(),
"rules" => ["required"]
],
"email" => [
"name" => "email",
"type" => Type::string(),
"rules" => ["required", "email"]
]
];
}
//...
}
當(dāng)你執(zhí)行修改的時(shí)候, 會(huì)返回驗(yàn)證錯(cuò)誤. 由于 GraphQL 規(guī)范定義了錯(cuò)誤的格式,因此會(huì)將驗(yàn)證錯(cuò)誤消息作為額外的 validation 屬性添加到錯(cuò)誤對(duì)象中。為了找到驗(yàn)證錯(cuò)誤,應(yīng)該檢查一個(gè) message 等于 validation 的時(shí)候,然后 validation 屬性將包含 Laravel Validator 返回的正常錯(cuò)誤消息信息.
{
"data": {
"updateUserEmail": null
},
"errors": [
{
"message": "validation",
"locations": [
{
"line": 1,
"column": 20
}
],
"validation": {
"email": [
"The email is invalid."
]
}
}
]
}
高級(jí)用法
查詢(xún)變量
GraphQL 允許你使用變量來(lái)查詢(xún)數(shù)據(jù), 從而不用在查詢(xún)中硬編碼值. 如下
query FetchUserByID($id: String) {
user(id: $id) {
id
email
}
}
當(dāng)你查詢(xún) GraphQL 的時(shí)候可以傳遞 variables 參數(shù)
http://homestead.app/graphql?query=query+FetchUserByID($id:String){user(id:$id){id,email}}&variables={"id":"1"}
查詢(xún)嵌入資源
如果想查詢(xún)嵌入資源
query FetchUser{
user(id: 123456789) {
id
posts(id: 987654321) {
id
}
}
}
你需要在 UserType 中添加 post 字段并且實(shí)現(xiàn) resolveField 方法
public function fields()
{
return [
"id" => [
"type" => Type::nonNull(Type::string()),
"description" => "Id of user",
],
"posts" => [
"args" => [
"id" => [
"type" => Type::string(),
"description" => "id of the post",
],
],
"type" => Type::listOf(GraphQL::type("Post")),
"description" => "post description",
],
];
}
public function resolvePostsField($root, $args)
{
if (isset($args["id"])) {
return $root->posts->where("id", $args["id"]);
}
return $root->posts;
}
枚舉
美劇類(lèi)型是一個(gè)特殊類(lèi)型的標(biāo)量變量, 用來(lái)限制一系列的允許的數(shù)據(jù), 可以查看這里閱讀更多的信息
首先創(chuàng)建一個(gè) Enum 作為 GraphQLType 的擴(kuò)展類(lèi)型
"Episode",
"description" => "The types of demographic elements",
"values" => [
"NEWHOPE" => "NEWHOPE",
"EMPIRE" => "EMPIRE",
"JEDI" => "JEDI",
],
];
}
注冊(cè) Enum 在 config/graphql.php 的 types 數(shù)組
// config/graphql.php "types" => [TestEnum" => TestEnumType::class ];
然后如下使用
[
"type" => GraphQL::type("TestEnum")
]
]
}
}
接口
你可以使用接口來(lái)限制一系列的字段, 閱讀更多的消息點(diǎn)擊這里
一系列的接口
"Character",
"description" => "Character interface.",
];
public function fields() {
return [
"id" => [
"type" => Type::nonNull(Type::int()),
"description" => "The id of the character."
],
"appearsIn" => [
"type" => Type::nonNull(Type::listOf(GraphQL::type("Episode"))),
"description" => "A list of episodes in which the character has an appearance."
],
];
}
public function resolveType($root) {
// Use the resolveType to resolve the Type which is implemented trough this interface
$type = $root["type"];
if ($type === "human") {
return GraphQL::type("Human");
} else if ($type === "droid") {
return GraphQL::type("Droid");
}
}
}
類(lèi)型實(shí)現(xiàn)
"Human",
"description" => "A human."
];
public function fields() {
return [
"id" => [
"type" => Type::nonNull(Type::int()),
"description" => "The id of the human.",
],
"appearsIn" => [
"type" => Type::nonNull(Type::listOf(GraphQL::type("Episode"))),
"description" => "A list of episodes in which the human has an appearance."
],
"totalCredits" => [
"type" => Type::nonNull(Type::int()),
"description" => "The total amount of credits this human owns."
]
];
}
public function interfaces() {
return [
GraphQL::type("Character")
];
}
}
自定義字段
你同樣可以定義一個(gè)字段類(lèi), 如果你想在多個(gè)類(lèi)型中重用他們.
namespace AppGraphQLFields;
use GraphQLTypeDefinitionType;
use FolkloreGraphQLSupportField;
class PictureField extends Field {
protected $attributes = [
"description" => "A picture"
];
public function type(){
return Type::string();
}
public function args()
{
return [
"width" => [
"type" => Type::int(),
"description" => "The width of the picture"
],
"height" => [
"type" => Type::int(),
"description" => "The height of the picture"
]
];
}
protected function resolve($root, $args)
{
$width = isset($args["width"]) ? $args["width"]:100;
$height = isset($args["height"]) ? $args["height"]:100;
return "http://placehold.it/".$width."x".$height;
}
}
你可以在 type 聲明中使用他們
namespace AppGraphQLType;
use GraphQLTypeDefinitionType;
use FolkloreGraphQLSupportType as GraphQLType;
use AppGraphQLFieldsPictureField;
class UserType extends GraphQLType {
protected $attributes = [
"name" => "User",
"description" => "A user"
];
public function fields()
{
return [
"id" => [
"type" => Type::nonNull(Type::string()),
"description" => "The id of the user"
],
"email" => [
"type" => Type::string(),
"description" => "The email of user"
],
//Instead of passing an array, you pass a class path to your custom field
"picture" => PictureField::class
];
}
}
加載關(guān)聯(lián)關(guān)系
傳遞給 query 的 resolve 方法的第三個(gè)參數(shù)是 GraphQLTypeDefinitionResolveInfo 的實(shí)例, 允許你從請(qǐng)求中取回指定的 key. 下面是一個(gè)使用這個(gè)參數(shù)的例子來(lái)獲取關(guān)聯(lián)模型的數(shù)據(jù). 如下
namespace AppGraphQLQuery;
use GraphQL;
use GraphQLTypeDefinitionType;
use GraphQLTypeDefinitionResolveInfo;
use FolkloreGraphQLSupportQuery;
use AppUser;
class UsersQuery extends Query
{
protected $attributes = [
"name" => "Users query"
];
public function type()
{
return Type::listOf(GraphQL::type("user"));
}
public function args()
{
return [
"id" => ["name" => "id", "type" => Type::string()],
"email" => ["name" => "email", "type" => Type::string()]
];
}
public function resolve($root, $args, $context, ResolveInfo $info)
{
$fields = $info->getFieldSelection($depth = 3);
$users = User::query();
foreach ($fields as $field => $keys) {
if ($field === "profile") {
$users->with("profile");
}
if ($field === "posts") {
$users->with("posts");
}
}
return $users->get();
}
}
你的 UserType 可能看起來(lái)是這個(gè)樣子的
"User",
"description" => "A user",
];
/**
* @return array
*/
public function fields()
{
return [
"uuid" => [
"type" => Type::nonNull(Type::string()),
"description" => "The uuid of the user"
],
"email" => [
"type" => Type::nonNull(Type::string()),
"description" => "The email of user"
],
"profile" => [
"type" => GraphQL::type("Profile"),
"description" => "The user profile",
],
"posts" => [
"type" => Type::listOf(GraphQL::type("Post")),
"description" => "The user posts",
]
];
}
}
這樣我們有一個(gè) profile 和一個(gè) post 類(lèi)型作為期待的返回關(guān)聯(lián)關(guān)系數(shù)據(jù)
class ProfileType extends GraphQLType
{
protected $attributes = [
"name" => "Profile",
"description" => "A user profile",
];
public function fields()
{
return [
"name" => [
"type" => Type::string(),
"description" => "The name of user"
]
];
}
}
class PostType extends GraphQLType
{
protected $attributes = [
"name" => "Post",
"description" => "A post",
];
public function fields()
{
return [
"title" => [
"type" => Type::nonNull(Type::string()),
"description" => "The title of the post"
],
"body" => [
"type" => Type::string(),
"description" => "The body the post"
]
];
}
}
最后你的查詢(xún)可能是這個(gè)樣子, 使用 URL
http://homestead.app/graphql?query=query+FetchUsers{users{uuid, email, team{name}}}
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/26278.html
showImg(https://segmentfault.com/img/bV6aHV?w=1280&h=800); 社區(qū)優(yōu)秀文章 Laravel 5.5+passport 放棄 dingo 開(kāi)發(fā) API 實(shí)戰(zhàn),讓 API 開(kāi)發(fā)更省心 - 自造車(chē)輪。 API 文檔神器 Swagger 介紹及在 PHP 項(xiàng)目中使用 - API 文檔撰寫(xiě)方案 推薦 Laravel API 項(xiàng)目必須使用的 8 個(gè)...
摘要:代碼示例產(chǎn)品列表和用戶(hù)列表的例子昨天我們學(xué)習(xí)了在中搭建環(huán)境,現(xiàn)在我們來(lái)學(xué)習(xí)的??梢蕴嵘{(diào)用的靈活性,我們可以像寫(xiě)數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)句一樣來(lái)請(qǐng)求來(lái)獲取所需要的數(shù)據(jù),這對(duì)構(gòu)建復(fù)雜的查詢(xún)來(lái)說(shuō)非常有用。 showImg(https://segmentfault.com/img/remote/1460000017906835?w=1280&h=720); 代碼示例:產(chǎn)品列表和用戶(hù)列表的 API 例子 ...
摘要:獲取標(biāo)簽及相關(guān)通常,我們會(huì)在博客首頁(yè)設(shè)計(jì)一個(gè)有分類(lèi)的文章列表,這就要求在發(fā)布時(shí)需要選擇對(duì)應(yīng)的。這里我用的是的和的庫(kù),核心代碼如下結(jié)合開(kāi)發(fā)個(gè)人博客的核心內(nèi)容基本就這么多了,具體代碼歡迎查看,一起踩坑。 作為一個(gè)程序員,搭建一個(gè)個(gè)人博客幾乎是所有人的需求,一來(lái)比較酷,二來(lái)也可以記錄自己的學(xué)習(xí)和生活總結(jié)。但如果你不是全棧工程師,實(shí)現(xiàn)這個(gè)需求還是有點(diǎn)麻煩。后端搭建一套現(xiàn)有的前端框架及前端寫(xiě)AP...
最近寫(xiě)了一個(gè)node項(xiàng)目,主要使用到的技術(shù)有: koa2 // nodejs 框架 koa-router // koa路由 graphql // 查詢(xún)api typescript // 強(qiáng)類(lèi)型語(yǔ)言 jwt // 授權(quán) typeorm // typescript的一個(gè)orm mysql2 // 內(nèi)容數(shù)據(jù)庫(kù) mongodb // 日志存儲(chǔ)數(shù)據(jù)庫(kù) redis // 服務(wù)器緩存 項(xiàng)目結(jié)構(gòu):sh...
閱讀 3201·2021-11-23 09:51
閱讀 2046·2021-09-09 09:32
閱讀 1136·2019-08-30 15:53
閱讀 3024·2019-08-30 11:19
閱讀 2542·2019-08-29 14:15
閱讀 1501·2019-08-29 13:52
閱讀 600·2019-08-29 12:46
閱讀 2884·2019-08-26 12:18