You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为Mojo::UserAgent添加Wikidata角色并扩展响应的可行性与实现

为Mojo::UserAgent实现Wikidata SPARQL查询角色的方案

1. 这种做法是否不妥?

完全没问题,这是符合Mojo生态设计思路的实践。Mojo本身就推崇用**角色(Role)**扩展类的功能,针对Wikidata SPARQL服务的响应做封装,既可以让代码更简洁易用,又不会污染全局的Mojo::UserAgent或Mojo::Message::Response对象——只针对该角色生成的事务响应做处理即可,不会影响其他场景下的使用。

2. 具体实现方案

我们可以分两个部分完成:一是给Mojo::UserAgent添加query方法的角色,二是给响应对象添加解析SPARQL结果的角色,确保只有通过该角色发起的请求才会获得增强的响应处理能力。

步骤1:实现Mojo::UserAgent的Wikidata角色

这个角色负责封装SPARQL请求的发送逻辑,并在请求成功后为响应对象附加解析角色。

package Mojo::UserAgent::Role::Wikidata;
use Mojo::Base -role;

sub query {
    my ($self, $sparql) = @_;

    # 发送SPARQL请求到Wikidata查询端点
    my $tx = $self->post(
        'https://query.wikidata.org/sparql',
        { Accept => 'application/sparql-results+json' }, # 指定返回JSON格式结果
        form => { query => $sparql }
    );

    # 仅在请求成功时,为响应对象添加结果解析角色
    $tx->res->with_roles('+WikidataResults') if $tx->success;

    return $tx;
}

1;

步骤2:实现响应对象的结果解析角色

这个角色负责解析Wikidata返回的SPARQL JSON结果,提供items方法直接返回易用的哈希数组。

package Mojo::Message::Response::Role::WikidataResults;
use Mojo::Base -role;

sub items {
    my $self = shift;
    my $json = $self->json;

    # 处理空结果或格式异常的情况
    return [] unless $json->{results} && $json->{results}->{bindings};

    # 将SPARQL的bindings结构转换为简洁的哈希数组
    return [
        map {
            my $binding = $_;
            +{ map { $_ => $binding->{$_}->{value} } keys %$binding }
        } @{$json->{results}->{bindings}}
    ];
}

1;

使用示例

按照你期望的方式调用即可:

use Mojo::UserAgent;

my $ua = Mojo::UserAgent->new->with_roles('+Wikidata');

# 示例SPARQL查询:获取10个人类条目
my $tx = $ua->query(q{
    SELECT ?item ?itemLabel 
    WHERE { 
        ?item wdt:P31 wd:Q5 . 
        SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } 
    } 
    LIMIT 10
});

if ($tx->success) {
    my $items = $tx->res->items;
    foreach my $item (@$items) {
        say "条目URI: $item->{item}, 名称: $item->{itemLabel}";
    }
} else {
    my ($err, $code) = $tx->error;
    say $code ? "请求失败(状态码$code): $err" : "连接错误: $err";
}

额外说明

  • 隔离性:只有通过$ua->query发起的请求,其响应对象才会被附加WikidataResults角色,不会影响Mojo::UserAgent的其他请求。
  • 扩展性:可以根据需求修改items方法,比如保留SPARQL结果中的数据类型(如type、datatype字段),或者添加其他辅助方法(比如count返回结果总数)。
  • 错误处理:务必先通过$tx->success判断请求是否成功,再调用items方法,避免因响应格式异常导致报错。

内容的提问来源于stack exchange,提问作者simone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:33:46