使用JSON模式免费模拟API
JSON::Schema::ToJSON是一个模块,它接受一个JSON模式,并生成符合该模式的 数据结构。以下是一个快速脚本,用于根据模式生成数据结构:
#!/usr/bin/perl
# gen-json - create json from a schema filepath
use Data::Dumper;
use JSON::Schema::ToJSON;
my $generator = JSON::Schema::ToJSON->new();
my $schema = do { local($/);<> }; # slurp the filepath in @ARGV
my $data = $generator->json_schema_to_json(schema_str => $schema);
print Dumper($data);
要运行它,我需要传入一个JSON模式的文件路径,在这个例子中,user.json
描述了一个Web应用用户。
$ ./gen-json user.json
$VAR1 = {
'email_address' => 'HfeiJzddxVTg@AspFqfgUKivV.com',
'birthdate' => '2014-01-14T00:59:43.000Z',
'active' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
'cell_phone_number' => '043 185 8956',
'roles' => [
'manager',
'trainer',
'admin'
],
'display_name' => 'Pswgfkjzdc',
'password' => 'QI0RQDR9A7W2EtuNHaQKvBFQp67oO0Ld',
'login' => '7oRSCeREi9sWm',
'full_name' => 'Oiqmqdr Frfxrzkzfjn',
};
脚本创建了一个新的JSON::Schema::ToJSON
对象,名为$generator
,将JSON模式吸入到$schema
中,并将生成的数据结构分配给$data
。然后,通过Data::Dumper
将$data
格式化输出到STDOUT。注意,打印到终端的数据是符合规范但不真实的。
模拟API
使用JSON模式描述API端点是Swagger的常见做法。Swagger将使用模式生成文档,并提供请求/响应测试工具。我们可以通过使用它们来模拟API端点来使JSON模式更加有用。想象一下,你已经定义了一个API,但还没有构建它:你可以创建API端点,并返回由JSON::Schema::ToJSON
模拟的数据,这样前端开发就可以在不等待后端准备好时开始。
假设我们有一个以下Swagger文档(一个JSON模式),它定义了一个单个API路由/user
。
{
"swagger": "2.0",
"schemes": [
"https"
],
"produces": [
"application/json"
],
"paths": {
"/user": {
"get": {
"summary": "returns a user for a given id",
"parameters": [
{
"name": "id",
"in": "path",
"type": "string"
}
],
"responses": {
"200": {
"description": "Objects matching the search term",
"schema": {
"type": "object",
"properties": {
"login": {
"type": "string",
"pattern": "[0-9A-Za-z]{5,32}"
},
"full_name": {
"type": "string",
"pattern": "[A-Z][a-z]{3,10} [A-Z][a-z]{3,20}"
},
"display_name": {
"type": "string",
"pattern": "[A-Z][a-z]{3,10}"
},
"birthdate": {
"type": "string",
"format": "date-time"
},
"email_address": {
"type": "string",
"format": "email"
},
"cell_phone_number": {
"type": "string",
"pattern": "\\d{3} \\d{3} \\d{4}"
},
"password": {
"type": "string",
"pattern": "[0-9A-Za-z]{8,32}"
},
"roles": {
"type": "array",
"minItems": 1,
"maxItems": 4,
"uniqueItems": true,
"items": {
"type": "string",
"enum": [ "admin", "manager", "trainer", "member" ]
}
},
"active": {
"type": "boolean"
}
}
}
}
}
}
}
}
}
这是一个Mojolicious::Lite应用,用于提供模拟的路由。
use Mojolicious::Lite;
use JSON::XS 'decode_json';
use JSON::Schema::ToJSON;
my $generator = JSON::Schema::ToJSON->new();
my $json = do { open my $fh, '<', 'swaggerdoc.json'; local($/);<$fh> };
my $swaggerdoc = decode_json($json);
get '/user' => sub {
my $self = shift;
my $route_def = $swaggerdoc->{paths}{'/user'}{get}{responses}{200}{schema};
my $response = $generator->json_schema_to_json(schema => $route_def);
$self->render(json => $response);
};
app->start;
此应用在启动时吸入并解码Swagger文档,将结果保存到$swaggerdoc
中,并声明一个/user
路由,该路由从$swaggerdoc
中提取API定义,并使用JSON::Schema::ToJSON
生成响应,并将其呈现。让我们测试一下这个应用。
$ hypnotoad user-app.pl
[Wed Sep 20 14:19:49 2017] [info] Listening at "http://*:8080"
Server available at http://127.0.0.1:8080
$ curl localhost:8080/user
{"active":false,"birthdate":"2009-08-30T17:47:32.000Z","cell_phone_number":"254 403 0133","display_name":"Nyzhoyp","email_address":"gEyRQXRPrlzL@CvuRitFtArXv.com","full_name":"Wmpgrd Bnaazxguekqtuezlu","login":"oAxgIvYQfbRmWHq4WifclhQxAI","password":"99wciSr8V","roles":["member","trainer","manager"]}
$ hypnotoad -s user-app.pl
Stopping Hypnotoad server 2177 gracefully.
首先,我用hypnotoad
将应用放入后台。接下来,我使用curl
测试端点,并正确返回了用户JSON。最后,我再次用hypnotoad
停止应用。看起来不错!
限制
当使用JSON::Schema::ToJSON
时,我遇到了一些限制。一个我已经提到了:它生成符合规范但不是真实的数据。这可能导致问题,如果您的对象属性有相互依赖关系,例如,first_name
应该是full_name
的子串。或者当生成日期时,有时随机日期时间不够精确:对于出生日期的真实日期,您可能希望某人是在10到80年前出生的。这个问题可以通过在JSON模式中使用正则表达式定义或使用JSON::Schema::ToJSON
的example_key
功能来部分缓解。
另一个问题是由于JSON模式本身的限制造成的:您可能无法以API返回的格式生成数据,例如,没有日期格式,只有日期时间。
但这些是微小的限制,我仍然坚信JSON::Schema::ToJSON是一种很好的方法,可以通过快速生成测试数据和/或模拟API来增强JSON模式的价值。
这篇文章最初发布在PerlTricks.com上。
标签
反馈
这篇文章有什么问题吗?请通过在GitHub上打开一个问题或拉取请求来帮助我们。