我正在开发一个 Crystal 应用程序并使用一个 API,该 API 的某些端点属性不一致地使用 PascalCase,而不是 CamelCase。不幸的是,这会导致
JSON::Serializable
出现问题,它不能顺利处理 PascalCase 属性。我已经能够使用 .from_json 成功反序列化来自其他 API 端点的响应,只要属性遵循驼峰命名约定即可。
解析响应:
api_url = "api.notmyapi.com"
client = HTTP::Client.new(api_url)
params = "/api?lets-get-some-pascal-case-i-guess"
json_response = PascalCaseResponse.from_json(client.get(params).body)
puts "json_response = #{json_response}" # No Bueno.
这在具有正确驼峰命名约定的所有其他端点上都可以正常工作。
但是,这是我的 Response 类的样子,它是直接根据 API 返回的 JSON 结构建模的...
class PascalCaseResponse
include JSON::Serializable
property PropertyOne : String
property SomeOtherProperty : String
....
property WhereAreTheCamels : String
end
...按照 API 端点响应的结构建模:
{
"PropertyOne":"I am a String",
"SomeOtherProperty":"So am I!",
....
"WhereAreTheCamels":"I do not know"
}
这会产生此异常:
/Users/tyler/Code/project $ crystal build src/main.cr; ./main
In src/responses/someresponse.cr:37:23
37 | property PropertyOne : String
^
Error: unexpected token: ":"
Unhandled exception: Missing JSON attribute: PropertyOne
让我相信这是 PascalCase 的是,当我将其属性更改为
propertyOne
时,它会继续抱怨 SomeOtherProperty
,但也抱怨 PropertyOne
,我觉得这很奇怪。
/Users/tyler/Code/project $ crystal build src/main.cr; ./main
In src/responses/someresponse.cr:38:16
38 | property SomeOtherProperty : String
^
Error: unexpected token: ":"
Unhandled exception: Missing JSON attribute: PropertyOne
如何告诉
JSON::Serializable
将 PascalCase JSON 属性映射到我显然想保留驼峰式命名的 Response 对象?
我已经尝试过了
@[JSON::Field(key: "PascalCase")]
property camelCase: String
但这不起作用,并且来自 Kotlin/Java 序列化背景,这似乎是可行的方法。
我错过了什么吗?
PropertyOne
不是有效的方法名称,因此会出现错误。您可以像您尝试过的那样使用 propertyOne
,但按照惯例,Crystal 方法名称是蛇形的。您使用 JSON::Field
的做法是正确的,但您必须对 every 属性执行此操作。比如:
class PascalCaseResponse
include JSON::Serializable
@[JSON::Field(key: "PropertyOne")]
property property_one : String
@[JSON::Field(key: "SomeOtherProperty")]
property some_other_property : String
@[JSON::Field(key: "WhereAreTheCamels")]
property where_are_the_camels : String
end
应该可以解决问题。