Hyperf方案 GraphQL接入
?php/** * 案例052GraphQL接入 * 说明用hyperf/graphql实现GraphQL查询支持类型系统和复杂查询 * 需要安装的包hyperf/graphql (^3.1)底层用webonyx/graphql-php */declare(strict_types1);namespaceApp\GraphQL;useGraphQL\Type\Definition\ObjectType;useGraphQL\Type\Definition\Type;useGraphQL\Type\Schema;useGraphQL\GraphQL;useGraphQL\Error\DebugFlag;/** * 定义User类型 * GraphQL的类型系统是强类型的每个字段都要定义类型 */classUserTypeextendsObjectType{publicfunction__construct(){parent::__construct([nameUser,description用户信息,fieldsfn()[// 用闭包延迟加载避免循环依赖id[typeType::int(),description用户ID],name[typeType::string(),description用户名],email[typeType::string()],age[typeType::int()],// 关联字段查用户时可以顺带查他的订单解决REST接口多次请求问题orders[typeType::listOf(TypeRegistry::order()),// User - [Order]resolvefunction($user){// 只有前端查了orders字段才会执行这里否则不查DBreturn\Hyperf\DbConnection\Db::table(orders)-where(user_id,$user[id])-get()-toArray();},],],]);}}/** * 定义Order类型 */classOrderTypeextendsObjectType{publicfunction__construct(){parent::__construct([nameOrder,fields[id[typeType::int()],amount[typeType::float()],status[typeType::string()],created_at[typeType::string()],],]);}}/** * 类型注册表避免重复创建类型实例GraphQL类型必须是单例 */classTypeRegistry{privatestaticarray$types[];publicstaticfunctionuser():UserType{returnself::$types[User]??newUserType();}publicstaticfunctionorder():OrderType{returnself::$types[Order]??newOrderType();}}/** * Query根类型读操作 */classQueryTypeextendsObjectType{publicfunction__construct(){parent::__construct([nameQuery,fields[// 查单个用户query { user(id: 1) { name, email } }user[typeTypeRegistry::user(),args[idType::nonNull(Type::int())],// id是必填参数resolvefunction($root,array$args){$user\Hyperf\DbConnection\Db::table(users)-find($args[id]);return$user?(array)$user:null;},],// 用户列表query { users(limit: 10) { id, name } }users[typeType::listOf(TypeRegistry::user()),args[limit[typeType::int(),defaultValue20],keyword[typeType::string()],],resolvefunction($root,array$args){$query\Hyperf\DbConnection\Db::table(users);if(!empty($args[keyword])){$query-where(name,like,%.$args[keyword].%);}return$query-limit($args[limit])-get()-toArray();},],],]);}}/** * Mutation根类型写操作 */classMutationTypeextendsObjectType{publicfunction__construct(){parent::__construct([nameMutation,fields[// 创建用户mutation { createUser(name: 张三, email: testtest.com) { id, name } }createUser[typeTypeRegistry::user(),args[nameType::nonNull(Type::string()),emailType::nonNull(Type::string()),ageType::int(),],resolvefunction($root,array$args){$id\Hyperf\DbConnection\Db::table(users)-insertGetId([name$args[name],email$args[email],age$args[age]??null,created_atdate(Y-m-d H:i:s),]);return\Hyperf\DbConnection\Db::table(users)-find($id);},],],]);}}/** * GraphQL HTTP Controller * 所有GraphQL请求都走这一个接口 POST /graphql */classGraphQLController{publicfunctionhandle(\Hyperf\HttpServer\Contract\RequestInterface$request):array{// 创建Schema把Query和Mutation注册进去$schemanewSchema([querynewQueryType(),mutationnewMutationType(),]);$body$request-post();$query$body[query]??;// GraphQL查询字符串$variables$body[variables]??null;// 变量前端传的参数// 执行GraphQL查询$resultGraphQL::executeQuery($schema,$query,null,null,$variables);// 开发环境输出详细错误生产环境不要暴露错误详情$debugenv(APP_ENV)dev?DebugFlag::INCLUDE_DEBUG_MESSAGE:DebugFlag::NONE;return$result-toArray($debug);}}