javascript - 根据输出 JSON 模式从输入 JSON 消息生成输出 JSON 消息
问题描述
我需要编写一个 NodeJS 解决方案和库来接收输入 JSON 数据,该解决方案必须将其转换为与提供的输出 JSON 模式匹配或验证的输出 JSON 数据。
目前,我有一个输入文件,它验证目标 JSON 模式,但缺少一些字段和默认值,业务规则允许作为转换的一部分。
源 JSON 如下:
{
"messageContext" : {
"statement" : "mediaDelivered",
"services" :[
"mss"
],
"domain":"my.xxx.yyy.create",
"function":"FCG"
},
"header" : {
"primaryEntityIDs":[
"my:png::abcxxxx"
],
"origin" : "my-png",
},
"data" :{
"operation": "CREATE",
"payload": {
"s3": "https://wildwildwest.amazonaws.com/png/myimg.mov"
}
}
}
生成的输出 JSON 必须匹配或验证到的 JSON 模式如下:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://schema.example.com/v1-0-0/schema.json",
"definitions": {
"header": {
"type": "object",
"title": "Message headers",
"description": "Header properties for the message.",
"required": [
"serializedVersion",
"correlationID",
"projectID",
"sourceMessageID",
"eventTimestamp",
"messageType",
"primaryEntityIDs"
],
"additionalProperties": false,
"properties": {
"serializedVersion": {
"type": "string",
"title": "serialized Version",
"description": "The version of the schema to validate this message against, the SchemaVer convention.",
"default": "1-0-0",
"pattern": "^([1-9][0-9]*)-(0|[1-9][0-9]*)-(0|[1-9][0-9]*)$",
"examples": [
"1-0-0"
]
},
"correlationID": {
"type": "string",
"title": "Correlation ID",
"description": "Use this field to pass on the ID from an upstream message. If you do not have an upstream message, please create a guid.",
"examples": [
"4fd5217e-a3d8-4ffc-8b8c-76ea9ba0ccdb"
]
},
"projectID": {
"type": "string",
"title": "Project ID",
"description": "An ID for the current project, which is a grouping of messages that apply to a specific business context. For example: a commission, creating a new content version, migrating programmes to a new brand.",
"examples": [
"4fd5217e-a3d8-4ffc-8b8c-76ea9ba0ccdb"
]
},
"sourceMessageID": {
"type": "string",
"title": "Source Message ID",
"description": "A unique ID for this message. Generated by the system that generates the message.",
"examples": [
"6b659d8f-bf4b-4dbe-8d31-5c6e9b8553b6"
]
},
"eventTimestamp": {
"type": "string",
"title": "Event Timestamp",
"description": "The ISO 8601 datetime at which this message was created. Generated by the system that generates the message.",
"examples": [
"2015-07-09T10:45:01.555Z"
],
"format": "date-time"
},
"expiryTime": {
"type": "string",
"title": "Expiry Time",
"description": "The ISO 8601 datetime at which the message is no longer applicable. For a status message this would mean that the status message should be ignored after this time and the information in it considered no longer true. Timezone must be provided. Accuracy greater than 1s is not supported, greater accuracy will be truncated. If not provided time for hh, mm, or ss defaults to 00.",
"examples":[
"2015-07-09T10:45:01.555Z"
],
"format": "date-time"
},
"origin": {
"type": "string",
"title": "origin",
"description": "The specific system that generated this message. This field is for information only, and should not be coupled to. To understand the source of a message, please use messageContext/Function. This allows for looser coupling between systems and for multiple systems to provide the same function.",
"examples": [
"media-selector"
]
},
"messageType": {
"type": "string",
"title": "Message Type",
"description": "The type of serialized message.",
"enum": [
"STATUS",
"COMMAND",
"ERROR"
],
"examples": [
"STATUS"
]
},
"inResponseTo": {
"type": "string",
"title": "In Response To",
"description": "The message ID that this message is in response to.",
"examples": [
"6b659d8f-bf4b-4dbe-8d31-5c6e9b8553b6"
]
},
"primaryEntityIDs": {
"type": "array",
"title": "Primary Entity IDs",
"description": "A list of equivalent IDs (preferably URIs) that systems use to describe the content this message is about. For example, this may contain a What's On UID, and a PEEPS version ID. Any further entity identifiers can be in the Payload section (for example the identifier of an availability document).",
"items": {
"type": "string",
"title": "ID",
"description": "IDs (preferably URIs) for my content identifiers.",
"examples": [
"urn:my:CMM1:uid:ABC123E/01",
"urn:my:DST1:pid:p00123"
]
}
}
}
},
"messageContext": {
"type": "object",
"title": "Message Context",
"description": "The message context, combined with the Content-IDs section should contain all of the information needed to understand the purpose of this message.",
"required": [
"domain",
"function",
"statement"
],
"additionalProperties": false,
"properties": {
"services": {
"type": "array",
"title": "Services",
"description": "A list of services that this message is relevant to. For example, the editorial description of a piece of content may be approved only for on-platform services, such as mediaplayer.",
"items": {
"type": "string",
"title": "A my service",
"examples": [
"mediaplayer",
"my-plus",
"twitter"
]
}
},
"domain": {
"type": "string",
"title": "Domain",
"description": "The top level address of the function sending the message. This follows a dot notation, starting with the company (e.g. my), moving down a domain hierarchy.",
"examples": [
"my.content.distribution"
]
},
"function": {
"type": "string",
"title": "Function",
"description": "The business function sending the message. This is the generic function that the sending system is providing when sending this message. For example, Media Selector is providing the function of AvailabilityManagement, within the distribution domain. One system may have grown to provide more than one function, in which case the specific function that applies to this message should be used.",
"examples": [
"availabilityManagement"
]
},
"contentTypes": {
"type": "array",
"title": "Content Types",
"description": "The content type that this message applies to. In the AvailabilityManagement example, this could separately message the availability of media, or document data separately, or together.",
"items": {
"type": "string",
"enum": [
"MEDIA",
"DOCUMENT"
],
"examples": [
"MEDIA"
]
}
},
"statement": {
"type": "string",
"title": "Statement",
"description": "The string statement being made by the message which describes the event. This must be past-tense.",
"pattern": "(^\\S+$)",
"examples": [
"receivedMedia",
"linkedToPlanningItem",
"renditionCreated"
]
}
}
},
"data": {
"type": "object",
"title": "Data",
"description": "Dictionary describing the type of data being transferred and the transfer method. Includes either a reference to a data entity or an entity itself in a JSON document.",
"additionalProperties": false,
"properties": {
"operation": {
"type": "string",
"title": "Operation",
"description": "The CRUD operation that was performed.",
"enum": [
"CREATE",
"READ",
"UPDATE",
"DELETE"
]
},
"entitySchema": {
"type": "string",
"title": "Entity Schema",
"description": "The schema used for the object in the Payload.",
"examples": [
"http://url.my.dev/package.schema.json"
]
},
"entityType": {
"type": "string",
"title": "Entity Type",
"description": "The type of entity being provided in the Payload.",
"examples": [
"package"
]
}
},
"anyOf": [
{
"required": [
"payload"
],
"properties": {
"payload": {
"type": "object",
"title": "Payload",
"description": "The data entity being transferred. If both a reference and a payload are provided, then the objects in both must be identical.",
"properties": {},
"additionalProperties": true
}
}
},
{
"required": [
"reference"
],
"properties": {
"reference": {
"type": "string",
"title": "Reference",
"description": "A reference to the data entity being transferred. If both a reference and a payload are provided, then the objects in both must be identical.",
"examples": [
"https://url.my.dev/3b0f45d6-9051-4939-974f-8cbb7774b1db"
]
}
}
}
]
}
}
}
规则如下:
我一直在研究并想知道您对在 NodeJS Javascript 中解决此问题的最佳方法和 Node 库的想法。
解决方案
我发现 Joi 库非常适合我的用例。我已经测试并使用了它,它对我有用,并且给了我需要控制来强制执行模式的约束。
https://www.npmjs.com/package/joi
另一个可能有用的库是https://www.npmjs.com/package/is-my-json-valid。但是,我还没有深入测试过这个库。
推荐阅读
- ios - iOS 类似 Android Animator(Set) 的复杂动画协调
- typescript - 带有动态分配的 Typescript 2.9 错误
- sql - 使用 Sql Agent 部署 Sql Analysis Services 时出错
- ffmpeg - 如何在不重新启动 ffmpeg 命令正在播放的视频流的情况下更改视频的 fps?
- java - 使用布尔值或对象字段反序列化 json
- r - R编程:多个表上的ifelse
- regex - 使用正则表达式解析 SCAPROC 日志文件
- magento2 - 为 magento 站点利用浏览器缓存
- xml - XSL-FO:设置固定的静态内容高度?
- java - Internet Explorer 未选择网页上的元素