为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
相关产品推荐
相关产品推荐

