定制 ray/web-query 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ray/web-query

Composer 安装命令:

composer require ray/web-query

包简介

Web API access mapping framework for Ray.MediaQuery

README 文档

README

Web API access mapping framework for Ray.MediaQuery.

Installation

composer require ray/web-query

Note: This package builds on ray/media-query, which provides the core query infrastructure (parameter injection, logging, etc.).

Usage

Define an interface

Annotate the methods with #[WebQuery], giving each one a query ID:

<?php
use Ray\MediaQuery\Annotation\WebQuery;

interface UserApiInterface
{
    #[WebQuery('user_item')]
    public function get(string $id): array;
}

Create a web query configuration file

web_query.json maps each query ID to an HTTP method and a URI template:

{
  "webQuery": [
    {"id": "user_item", "method": "GET", "path": "https://{domain}/users/{id}"}
  ]
}

Install the module

MediaQueryWebModule is installed into MediaQueryBaseModule. The interfaces are registered with Queries::fromClasses():

<?php
use Ray\Di\Injector;
use Ray\MediaQuery\MediaQueryBaseModule;
use Ray\MediaQuery\MediaQueryWebModule;
use Ray\MediaQuery\Queries;
use Ray\MediaQuery\WebQueryConfig;

$queries = Queries::fromClasses([UserApiInterface::class]);
$webConfig = new WebQueryConfig('web_query.json', ['domain' => 'api.example.com']);

$module = new MediaQueryBaseModule($queries);
$module->install(new MediaQueryWebModule($webConfig));

$injector = new Injector($module);
$api = $injector->getInstance(UserApiInterface::class);

$user = $api->get('123'); // GET https://api.example.com/users/123

URI template variables are filled from the method arguments and the bindings passed to WebQueryConfig (here {domain} comes from the bindings and {id} from the get() argument).

Response types

The return type of the interface method selects how the HTTP response is handled:

Return type Result
array JSON body decoded to an array
string Raw response body
PSR-7 MessageInterface The HTTP message object

Mapping responses to a domain object

Instead of a raw array, a method can return typed, immutable domain objects. Give #[WebQuery] a factory (and a type) — this is the same factory mechanism ray/media-query provides for #[DbQuery], applied to HTTP responses.

<?php
use Ray\MediaQuery\Annotation\WebQuery;

interface ProductApiInterface
{
    #[WebQuery('product_item', type: 'row', factory: ProductFactory::class)]
    public function get(string $id): Product;

    #[WebQuery('product_list', factory: ProductFactory::class)]
    /** @return array<Product> */
    public function list(string $status): array;
}

The factory is resolved through the DI injector, so it can depend on domain services and apply business logic while building the object:

<?php
final class ProductFactory
{
    public function __construct(
        private TaxCalculator $tax,
    ) {
    }

    public function factory(string $name, int $price): Product
    {
        return new Product($name, $this->tax->applyTax($price));
    }
}

final class Product
{
    public function __construct(
        public readonly string $name,
        public readonly int $price,
    ) {
    }
}

The decoded JSON is passed to the factory method as named arguments: each JSON key is matched to a parameter by name, unknown keys are ignored, and a missing required argument throws InvalidWebFactoryKeyException. (This is the web counterpart of media-query's positional PDO::FETCH_FUNC binding.)

type selects single object vs. list:

type JSON response Result
'row' object {...} one object
'row_list' array [{...}, {...}] array<Object>

type defaults to 'row_list'. A 'row' method whose response is a list takes the first element; a 'row_list' method whose response is a single object wraps it into a one-element list.

You can also map straight to an entity without a factory: when the return type (or the @return array<Entity> docblock) is a class, each response is hydrated through the entity constructor.

#[WebQuery('product_item', type: 'row')]
public function get(string $id): Product; // built via Product::__construct

Composing results with PostFetch

To wrap or aggregate the fetched objects into another type (totals, metadata, …), let the return type implement PostFetchInterface. Its static fromContext() receives the fetch result and returns the final object. It runs after the factory, carries no dependencies by design, and is the web analogue of media-query's PostQueryInterface (named PostFetch because a web call is a single fetch, with no multi-statement query context to span).

<?php
use Ray\MediaQuery\PostFetchContext;
use Ray\MediaQuery\PostFetchInterface;

final class ProductList implements PostFetchInterface
{
    /** @param array<Product> $items */
    public function __construct(
        public readonly array $items,
        public readonly int $total,
    ) {
    }

    public static function fromContext(PostFetchContext $context): static
    {
        /** @var array<Product> $items */
        $items = is_array($context->result) ? $context->result : [];

        return new self($items, count($items));
    }
}
#[WebQuery('product_list', factory: ProductFactory::class)]
public function listAggregate(string $status): ProductList;

PostFetchContext exposes the fetch result, the original method arguments (query), and the #[WebQuery] annotation (webQuery).

Features

  • Web API Queries: Execute HTTP requests via interface methods
  • URI Template Support: Dynamic URL parameter binding with {param} syntax
  • Multiple Response Types: JSON array, string, or PSR-7 message
  • Domain Object Mapping (BDR): Map responses to typed domain objects via an injectable factory, with optional PostFetch composition
  • Parameter Injection: Automatic parameter conversion and injection
  • HTTP Client Integration: Built on the Guzzle HTTP client

Requirements

  • PHP 8.2+
  • ray/media-query ^1.0

ray/web-query 适用场景与选型建议

ray/web-query 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 07 月 30 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 ray/web-query 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 ray/web-query 我们能提供哪些服务?
定制开发 / 二次开发

基于 ray/web-query 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 23
  • 依赖项目数: 0
  • 推荐数: 1

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-07-30