在 Laravel 6、LightHouse 5、Module 中,自定义验证规则的使用
1、现阶段需要在 GraphQL API 中实现一个删除缓存标识的接口。参考 Shopify 的示例。当缓存标识不存在时,响应失败。如图1
mutation DeleteThemeSessionId($sessionId: String!) { onlineStoreEditorSessionDelete(sessionId: $sessionId) { deletedSessionId userErrors { field message __typename } __typename } }
{ "sessionId": "H9Mc8FwH5Eu5LR37XAzsehh4" }
{ "data": { "onlineStoreEditorSessionDelete": { "deletedSessionId": null, "userErrors": [ { "field": [ "sessionId" ], "message": "在线商店编辑器访问不存在", "__typename": "UserError" } ], "__typename": "OnlineStoreEditorSessionDeletePayload" } }, "extensions": { "cost": { "requestedQueryCost": 10, "actualQueryCost": 10, "throttleStatus": { "maximumAvailable": 1000, "currentlyAvailable": 990, "restoreRate": 50 } } } }
2、由于验证此缓存标识是否存在的规则,会用于大量的 API 中。最张决定自定义验证规则,以复用此验证规则。
3、由于是在模块中编写验证规则。module:make-rule Create a new validation rule for the specified module.
PS E:\wwwroot\object> php artisan help module:make-rule Description: Create a new validation rule for the specified module. Usage: module:make-rule <name> [<module>] Arguments: name The name of the rule class. module The name of module will be used. Options: -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question --env[=ENV] The environment the command should run under -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug PS E:\wwwroot\object> php artisan module:make-rule ThemeEditor/ThemeEditorCodeExistsRule ThemeStore Created : E:/wwwroot/object/Modules/ThemeStore/Rules/ThemeEditor/ThemeEditorCodeExistsRule.php PS E:\wwwroot\object>
4、编辑规则类,判断缓存标识是否存在。/Modules/ThemeStore/Rules/ThemeEditor/ThemeEditorCodeExistsRule.php
<?php namespace Modules\ThemeStore\Rules\ThemeEditor; use Illuminate\Contracts\Validation\Rule; use Illuminate\Support\Facades\Cache; use Modules\ThemeStore\Resolver\ThemeEditor\ThemeEditorResolver; class ThemeEditorCodeExistsRule implements Rule { /** * Determine if the validation rule passes. * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { return Cache::tags([ThemeEditorResolver::TAG_THEME_EDITOR, ThemeEditorResolver::TAG_THEME_EDITOR_CODE])->has($value); } /** * Get the validation error message. * * @return string */ public function message() { return 'The validation error message.'; } }
5、编辑 /ThemeStore/Resources/graphql/theme_editor.graphql 。使用 @rules 指令,通过完全限定的类名引用自定义验证规则:ThemeEditorCodeExistsRule
extend type Mutation { ... "删除主题编辑标识" onlineStoreThemeEditorCodeDelete(themeEditorCode: String! @rules(apply: ["Modules\\ThemeStore\\Rules\\ThemeEditor\\ThemeEditorCodeExistsRule"])): ThemeEditorCodeDeletePayload @field(resolver: "Modules\\ThemeStore\\Resolver\\ThemeEditor\\DeleteThemeEditorCodeResolver") } type ThemeEditorCodeDeletePayload { deletedThemeEditorCode: String }
6、新生成了一个缓存标识:vRYbn7NQiEWMbH2G6sXB8AE4aoBIk4JQOw2p,先测试验证失败的情况。
mutation { onlineStoreThemeEditorCodeDelete(themeEditorCode: "vRYbn7NQiEWMbH2G6sXB8AE4aoBIk4JQOw2p0") { deletedThemeEditorCode } }
{ "errors": [ { "message": "Validation failed for the field [onlineStoreThemeEditorCodeDelete].", "extensions": { "validation": { "themeEditorCode": [ "The validation error message." ] }, "category": "validation" }, "locations": [ { "line": 2, "column": 3 } ], "path": [ "onlineStoreThemeEditorCodeDelete" ], "trace": [ ... ] } ], "data": { "onlineStoreThemeEditorCodeDelete": null } }
7、新建模块下的 /Modules/ThemeStore/Resources/lang/en/validation.php 语言文件。
<?php return [ 'custom' => [ 'theme_editor_code' => [ 'theme_editor_code_exists_rule' => 'The selected :attribute is invalid.', ], ], 'attributes' => [], ];
8、编辑规则类,/Modules/ThemeStore/Rules/ThemeEditor/ThemeEditorCodeExistsRule.php。从翻译文件中返回一个错误消息,从 message 方法中调用辅助函数 trans。
<?php namespace Modules\ThemeStore\Rules\ThemeEditor; use Illuminate\Contracts\Validation\Rule; use Illuminate\Support\Facades\Cache; use Modules\ThemeStore\Resolver\ThemeEditor\ThemeEditorResolver; class ThemeEditorCodeExistsRule implements Rule { /** * Determine if the validation rule passes. * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { return Cache::tags([ThemeEditorResolver::TAG_THEME_EDITOR, ThemeEditorResolver::TAG_THEME_EDITOR_CODE])->has($value); } /** * Get the validation error message. * * @return string */ public function message() { return trans('theme_store::validation.custom.theme_editor_code.theme_editor_code_exists_rule'); } }
9、再次测试验证失败的情况。The validation error message. 已经被替换为:The selected theme editor code is invalid.。如图2
mutation { onlineStoreThemeEditorCodeDelete(themeEditorCode: "vRYbn7NQiEWMbH2G6sXB8AE4aoBIk4JQOw2p0") { deletedThemeEditorCode } }
{ "errors": [ { "message": "Validation failed for the field [onlineStoreThemeEditorCodeDelete].", "extensions": { "validation": { "themeEditorCode": [ "The selected theme editor code is invalid." ] }, "category": "validation" }, "locations": [ { "line": 2, "column": 3 } ], "path": [ "onlineStoreThemeEditorCodeDelete" ], "trace": [ ... ] } ], "data": { "onlineStoreThemeEditorCodeDelete": null } }
10、新建模块下的 /Modules/ThemeStore/Resources/lang/zh_CN/validation.php 语言文件。
<?php return [ 'custom' => [ 'theme_editor_code' => [ 'theme_editor_code_exists_rule' => '所选的主题编辑标识无效。', ], ], 'attributes' => [], ];
11、当前语言区域被设置为:zh_CN 时,测试失败的响应,响应信息为中文。符合预期。如图3
{ "errors": [ { "message": "Validation failed for the field [onlineStoreThemeEditorCodeDelete].", "extensions": { "validation": { "themeEditorCode": [ "所选的主题编辑标识无效。" ] }, "category": "validation" }, "locations": [ { "line": 2, "column": 3 } ], "path": [ "onlineStoreThemeEditorCodeDelete" ], "trace": [ ... ] } ], "data": { "onlineStoreThemeEditorCodeDelete": null } }
12、可将 /Modules/ThemeStore/Resources/lang/en/validation.php 复制为 /Modules/ThemeStore/Resources/lang/en_US/validation.php。当语言区域设置为 en_US 时,/en_US/validation.php 的优先级高于 /en/validation.php。如果在 /en_US/validation.php 中查找不到,则会从 /en/validation.php 查找。测试失败的响应。
<?php return [ 'custom' => [], 'attributes' => [], ];
{ "errors": [ { "message": "Validation failed for the field [onlineStoreThemeEditorCodeDelete].", "extensions": { "validation": { "themeEditorCode": [ "The selected theme editor code is invalid." ] }, "category": "validation" }, "locations": [ { "line": 2, "column": 3 } ], "path": [ "onlineStoreThemeEditorCodeDelete" ], "trace": ... } ], "data": { "onlineStoreThemeEditorCodeDelete": null } }
13、注:theme_store 的名称源于 /ThemeStore/Providers/ThemeStoreServiceProvider.php
private $moduleNameLower = 'theme_store';
14、测试验证通过的情况,符合预期。如图4
mutation { onlineStoreThemeEditorCodeDelete(themeEditorCode: "vRYbn7NQiEWMbH2G6sXB8AE4aoBIk4JQOw2p") { deletedThemeEditorCode } }
{ "data": { "onlineStoreThemeEditorCodeDelete": { "deletedThemeEditorCode": "vRYbn7NQiEWMbH2G6sXB8AE4aoBIk4JQOw2p" } } }
近期评论