Laravel灯塔-跳过返回基于权限的字段



我已经安装了Laravel Lighthouse并构建了我的API端点。我有一些端点,我想只允许返回一些字段,这取决于用户的权限级别。

例如,我想从回复中完全删除电子邮件字段。我已经实现了我自己的ScopedField指令如下:

<?php
namespace AppGraphQLDirectives;
use GraphQLTypeDefinitionResolveInfo;
use IlluminateDatabaseEloquentModel;
use IlluminateSupportFacadesGate;
use NuwaveLighthouseSchemaDirectivesBaseDirective;
use NuwaveLighthouseSchemaValuesFieldValue;
use NuwaveLighthouseSupportContractsFieldMiddleware;
use NuwaveLighthouseSupportContractsGraphQLContext;
final class ScopedFieldDirective extends BaseDirective implements FieldMiddleware
{
public static function definition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
directive @scopedField(
"""
The ability to check permissions for.
"""
ability: [String]! = []

"""
The default value to return when ability is invalid
"""
default: String = null
) on FIELD_DEFINITION
GRAPHQL;
}

public function handleField(FieldValue $fieldValue, Closure $next)
{
$resolver = $fieldValue->getResolver();

$fieldValue->setResolver(function (
$root,
array $args,
GraphQLContext $context,
ResolveInfo $info
) use (
$resolver
) {
$resolve = fn() => $resolver($root, $args, $context, $info);
$default = fn() => $this->directiveArgValue('default', null);

if (!$root instanceof Model) {
return $resolve();
}

if (
($abilities = $this->directiveArgValue('ability'))
&& !Gate::check($abilities, $root)
) {
// null out our value
return $default();
}

return $resolve();
});

return $next($fieldValue);
}
}

下面是一个模式示例:

type User {
id: ID!

first_name: String!

email: String @scopedField(ability: ["read"])
}

这个指令意味着在每个字段的基础上,我可以拦截并返回一个默认值,例如null。但是如果我想从响应中完全移除这个字段呢?这是可能的/甚至是推荐的-或者我应该让字段可能为空吗?

谢谢,克里斯。

GraphQL提供了API中数据的完整且可理解的描述,使客户端能够准确地要求他们需要的内容,而不是更多。

graphQL的整个概念是避免抓取过度和抓取不足。给客户端null或'unauthenticated'是可以接受的。

如果你必须删除它,你可以使用灯塔操作结果事件。您将钩入请求的生命周期,获得作为集合的结果,并删除您想要的内容。

最新更新