Skip to content

Commit db449ff

Browse files
committed
Documentation HTTP hosting of schemas
1 parent 9d482a2 commit db449ff

File tree

6 files changed

+197
-6
lines changed

6 files changed

+197
-6
lines changed

README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ License: [MIT](LICENSE.md), 2019
1515

1616
Requirements: Any platform where [Node-RED](https://nodered.org) (1.0+) or [Node.js](https://nodejs.org) (10.0+) can run.
1717

18-
Here is an example of full Node-RED: [Node-RED_example_of_flow.json](examples/Node-RED_example_of_flow.json)
18+
Here is an example of full Node-RED flow: [Node-RED_example_of_flow.json](examples/Node-RED_example_of_flow.json)
1919

2020
![Node-RED flow](examples/Node-RED_example_of_flow.png)
2121

@@ -363,3 +363,33 @@ docker run -i -v tmp-schemas:/tmp --rm synchronicityiot/node-red-contrib-json-mu
363363
docker run -i -v tmp-schemas:/tmp --rm synchronicityiot/node-red-contrib-json-multi-schema json-multi-schema-validator | \
364364
jq -c .
365365
```
366+
367+
 
368+
369+
---
370+
371+
 
372+
373+
## Serving schemas
374+
375+
The three nodes are all expecting configuration files and corresponding schemas to be provided by HTTP.
376+
377+
While JSON Schemas are often publicly available (e.g. https://schema.org , https://smart-data-models.github.io/data-models/ ), it might not be the case for the list of JSON Schemas itself, the list of transformations, or the JSONata transformations.
378+
379+
Any HTTP server can be used to host those documents. This can also be done using Node-RED:
380+
381+
### Local Node-RED hosting
382+
383+
The same Node-RED instance can be used to host the various lists and custom schemas.
384+
385+
Here is an example of full Node-RED flow: [Node-RED_example_of_HTTP_flow.json](examples/Node-RED_example_of_HTTP_flow.json)
386+
387+
![Node-RED flow](examples/Node-RED_example_of_HTTP_flow.png)
388+
389+
Read more on the [Node-RED cookbook](https://cookbook.nodered.org/http/serve-json-content).
390+
391+
### Caching of schemas
392+
393+
Once downloaded, a copy of the schemas is saved on local disk (by default in `/tmp/`).
394+
395+
If schemas are updated without changing their URL, it is possible to either purge the local cache manually, or add a version number at the end of their URL, such as `https://example.net/a-schema.json?v2`
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
[
2+
{
3+
"id": "587d0d64.709bac",
4+
"type": "http in",
5+
"z": "51af8c53.929c6c",
6+
"name": "",
7+
"url": "/schemas/:schema",
8+
"method": "get",
9+
"upload": false,
10+
"swaggerDoc": "",
11+
"x": 1180,
12+
"y": 740,
13+
"wires": [
14+
[
15+
"55807652.b2dd38"
16+
]
17+
]
18+
},
19+
{
20+
"id": "d222ec97.269898",
21+
"type": "http response",
22+
"z": "51af8c53.929c6c",
23+
"name": "JSON response",
24+
"statusCode": "",
25+
"headers": {
26+
"content-type": "application/json"
27+
},
28+
"x": 1860,
29+
"y": 700,
30+
"wires": []
31+
},
32+
{
33+
"id": "eb83d168.8f37b8",
34+
"type": "template",
35+
"z": "51af8c53.929c6c",
36+
"name": "smart-data-models.json",
37+
"field": "payload",
38+
"fieldType": "msg",
39+
"format": "json",
40+
"syntax": "plain",
41+
"template": "[\n\t{\n\t\t\"query\": \"type\",\n\t\t\"cases\": {\n\t\t\t\"AeroAllergenObserved\": \"https://smart-data-models.github.io/data-models/specs/Environment/AeroAllergenObserved/schema.json\",\n\t\t\t\"AgriApp\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriApp/schema.json\",\n\t\t\t\"AgriCrop\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriCrop/schema.json\",\n\t\t\t\"AgriFarm\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriFarm/schema.json\",\n\t\t\t\"AgriGreenhouse\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriGreenhouse/schema.json\",\n\t\t\t\"AgriParcel\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriParcel/schema.json\",\n\t\t\t\"AgriParcelOperation\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriParcelOperation/schema.json\",\n\t\t\t\"AgriParcelRecord\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriParcelRecord/schema.json\",\n\t\t\t\"AgriPest\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriPest/schema.json\",\n\t\t\t\"AgriProductType\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/AgriProductType/schema.json\",\n\t\t\t\"AirQualityObserved\": \"https://smart-data-models.github.io/data-models/specs/Environment/AirQualityObserved/schema.json\",\n\t\t\t\"Alert\": \"https://smart-data-models.github.io/data-models/specs/Alert/alert-schema.json\",\n\t\t\t\"Animal\": \"https://smart-data-models.github.io/data-models/specs/AgriFood/Animal/schema.json\",\n\t\t\t\"ArrivalEstimation\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/ArrivalEstimation/schema.json\",\n\t\t\t\"Beach\": \"https://smart-data-models.github.io/data-models/specs/PointOfInterest/Beach/schema.json\",\n\t\t\t\"BikeHireDockingStation\": \"https://smart-data-models.github.io/data-models/specs/Transportation/Bike/BikeHireDockingStation/schema.json\",\n\t\t\t\"Building\": \"https://smart-data-models.github.io/data-models/specs/Building/Building/schema.json\",\n\t\t\t\"BuildingOperation\": \"https://smart-data-models.github.io/data-models/specs/Building/BuildingOperation/schema.json\",\n\t\t\t\"CrowdFlowObserved\": \"https://smart-data-models.github.io/data-models/specs/Transportation/CrowdFlowObserved/schema.json\",\n\t\t\t\"Device\": \"https://smart-data-models.github.io/data-models/specs/Device/Device/schema.json\",\n\t\t\t\"DeviceModel\": \"https://smart-data-models.github.io/data-models/specs/Device/DeviceModel/schema.json\",\n\t\t\t\"EVChargingStation\": \"https://smart-data-models.github.io/data-models/specs/Transportation/EVChargingStation/schema.json\",\n\t\t\t\"FlowerBed\": \"https://smart-data-models.github.io/data-models/specs/ParksAndGardens/FlowerBed/schema.json\",\n\t\t\t\"Garden\": \"https://smart-data-models.github.io/data-models/specs/ParksAndGardens/Garden/schema.json\",\n\t\t\t\"GreenspaceRecord\": \"https://smart-data-models.github.io/data-models/specs/ParksAndGardens/GreenspaceRecord/schema.json\",\n\t\t\t\"GtfsAccessPoint\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsAccessPoint/schema.json\",\n\t\t\t\"GtfsAgency\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsAgency/schema.json\",\n\t\t\t\"GtfsCalendarDateRule\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsCalendarDateRule/schema.json\",\n\t\t\t\"GtfsCalendarRule\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsCalendarRule/schema.json\",\n\t\t\t\"GtfsFrequency\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsFrequency/schema.json\",\n\t\t\t\"GtfsRoute\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsRoute/schema.json\",\n\t\t\t\"GtfsService\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsService/schema.json\",\n\t\t\t\"GtfsShape\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsShape/schema.json\",\n\t\t\t\"GtfsStation\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsStation/schema.json\",\n\t\t\t\"GtfsStop\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsStop/schema.json\",\n\t\t\t\"GtfsStopTime\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsStopTime/schema.json\",\n\t\t\t\"GtfsTransferRule\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsTransferRule/schema.json\",\n\t\t\t\"GtfsTrip\": \"https://smart-data-models.github.io/data-models/specs/UrbanMobility/GtfsTrip/schema.json\",\n\t\t\t\"KeyPerformanceIndicator\": \"https://smart-data-models.github.io/data-models/specs/KeyPerformanceIndicator/schema.json\",\n\t\t\t\"Museum\": \"https://smart-data-models.github.io/data-models/specs/PointOfInterest/Museum/schema.json\",\n\t\t\t\"NoiseLevelObserved\": \"https://smart-data-models.github.io/data-models/specs/Environment/NoiseLevelObserved/schema.json\",\n\t\t\t\"OffStreetParking\": \"https://smart-data-models.github.io/data-models/specs/Parking/OffStreetParking/schema.json\",\n\t\t\t\"OnStreetParking\": \"https://smart-data-models.github.io/data-models/specs/Parking/OnStreetParking/schema.json\",\n\t\t\t\"Open311ServiceRequest\": \"https://smart-data-models.github.io/data-models/specs/IssueTracking/Open311_ServiceRequest/schema.json\",\n\t\t\t\"Open311ServiceType\": \"https://smart-data-models.github.io/data-models/specs/IssueTracking/Open311_ServiceType/schema.json\",\n\t\t\t\"ParkingAccess\": \"https://smart-data-models.github.io/data-models/specs/Parking/ParkingAccess/schema.json\",\n\t\t\t\"ParkingGroup\": \"https://smart-data-models.github.io/data-models/specs/Parking/ParkingGroup/schema.json\",\n\t\t\t\"ParkingSpot\": \"https://smart-data-models.github.io/data-models/specs/Parking/ParkingSpot/schema.json\",\n\t\t\t\"PointOfInterest\": \"https://smart-data-models.github.io/data-models/specs/PointOfInterest/PointOfInterest/schema.json\",\n\t\t\t\"Road\": \"https://smart-data-models.github.io/data-models/specs/Transportation/Road/schema.json\",\n\t\t\t\"RoadSegment\": \"https://smart-data-models.github.io/data-models/specs/Transportation/RoadSegment/schema.json\",\n\t\t\t\"SmartPointOfInteraction\": \"https://smart-data-models.github.io/data-models/specs/PointOfInteraction/SmartPointOfInteraction/schema.json\",\n\t\t\t\"SmartSpot\": \"https://smart-data-models.github.io/data-models/specs/PointOfInteraction/SmartSpot/schema.json\",\n\t\t\t\"Streetlight\": \"https://smart-data-models.github.io/data-models/specs/StreetLighting/Streetlight/schema.json\",\n\t\t\t\"StreetlightControlCabinet\": \"https://smart-data-models.github.io/data-models/specs/StreetLighting/StreetlightControlCabinet/schema.json\",\n\t\t\t\"StreetlightGroup\": \"https://smart-data-models.github.io/data-models/specs/StreetLighting/StreetlightGroup/schema.json\",\n\t\t\t\"StreetlightModel\": \"https://smart-data-models.github.io/data-models/specs/StreetLighting/StreetlightModel/schema.json\",\n\t\t\t\"ThreePhaseAcMeasurement\": \"https://smart-data-models.github.io/data-models/specs/Energy/ThreePhaseAcMeasurement/schema.json\",\n\t\t\t\"TrafficFlowObserved\": \"https://smart-data-models.github.io/data-models/specs/Transportation/TrafficFlowObserved/schema.json\",\n\t\t\t\"UserActivity\": \"https://smart-data-models.github.io/data-models/specs/User/Activity/schema.json\",\n\t\t\t\"UserContext\": \"https://smart-data-models.github.io/data-models/specs/User/UserContext/schema.json\",\n\t\t\t\"Vehicle\": \"https://smart-data-models.github.io/data-models/specs/Transportation/Vehicle/Vehicle/schema.json\",\n\t\t\t\"VehicleModel\": \"https://smart-data-models.github.io/data-models/specs/Transportation/Vehicle/VehicleModel/schema.json\",\n\t\t\t\"WasteContainer\": \"https://smart-data-models.github.io/data-models/specs/WasteManagement/WasteContainer/schema.json\",\n\t\t\t\"WasteContainerIsle\": \"https://smart-data-models.github.io/data-models/specs/WasteManagement/WasteContainerIsle/schema.json\",\n\t\t\t\"WasteContainerModel\": \"https://smart-data-models.github.io/data-models/specs/WasteManagement/WasteContainerModel/schema.json\",\n\t\t\t\"WaterQualityObserved\": \"https://smart-data-models.github.io/data-models/specs/Environment/WaterQualityObserved/schema.json\",\n\t\t\t\"WeatherForecast\": \"https://smart-data-models.github.io/data-models/specs/Weather/WeatherForecast/schema.json\",\n\t\t\t\"WeatherObserved\": \"https://smart-data-models.github.io/data-models/specs/Weather/WeatherObserved/schema.json\",\n\t\t\t\"\": \"\"\n\t\t}\n\t}\n]",
42+
"output": "str",
43+
"x": 1590,
44+
"y": 700,
45+
"wires": [
46+
[
47+
"d222ec97.269898"
48+
]
49+
]
50+
},
51+
{
52+
"id": "24f6fab7.2318f6",
53+
"type": "template",
54+
"z": "51af8c53.929c6c",
55+
"name": "smart-data-transforms.json",
56+
"field": "payload",
57+
"fieldType": "msg",
58+
"format": "json",
59+
"syntax": "plain",
60+
"template": "[\n\t{\n\t\t\"query\": \"type='BasicVehicle' and latitude\",\n\t\t\"cases\": {\n\t\t\t\"true\": \"http://localhost:1880/schemas/OldVehicleToVehicle.jsonata.js\"\n\t\t}\n\t}\n]\n",
61+
"output": "str",
62+
"x": 1600,
63+
"y": 740,
64+
"wires": [
65+
[
66+
"d222ec97.269898"
67+
]
68+
]
69+
},
70+
{
71+
"id": "55807652.b2dd38",
72+
"type": "switch",
73+
"z": "51af8c53.929c6c",
74+
"name": "",
75+
"property": "req.params.schema",
76+
"propertyType": "msg",
77+
"rules": [
78+
{
79+
"t": "eq",
80+
"v": "smart-data-models.json",
81+
"vt": "str"
82+
},
83+
{
84+
"t": "eq",
85+
"v": "smart-data-transforms.json",
86+
"vt": "str"
87+
},
88+
{
89+
"t": "eq",
90+
"v": "OldVehicleToVehicle.jsonata.js",
91+
"vt": "str"
92+
},
93+
{
94+
"t": "else"
95+
}
96+
],
97+
"checkall": "false",
98+
"repair": false,
99+
"outputs": 4,
100+
"x": 1370,
101+
"y": 740,
102+
"wires": [
103+
[
104+
"eb83d168.8f37b8"
105+
],
106+
[
107+
"24f6fab7.2318f6"
108+
],
109+
[
110+
"41126013.dac2d"
111+
],
112+
[
113+
"81cb0a38.5a15d8"
114+
]
115+
]
116+
},
117+
{
118+
"id": "81cb0a38.5a15d8",
119+
"type": "http response",
120+
"z": "51af8c53.929c6c",
121+
"name": "",
122+
"statusCode": "404",
123+
"headers": {},
124+
"x": 1540,
125+
"y": 820,
126+
"wires": []
127+
},
128+
{
129+
"id": "41126013.dac2d",
130+
"type": "template",
131+
"z": "51af8c53.929c6c",
132+
"name": "OldVehicleToVehicle.jsonata.js",
133+
"field": "payload",
134+
"fieldType": "msg",
135+
"format": "text",
136+
"syntax": "plain",
137+
"template": "{\n\t\"id\": id,\n\t\"type\": \"Vehicle\",\n\t\"vehicleType\": vehicleType,\n\t\"category\": [\n\t\tcategory1\n\t],\n\t\"location\": {\n\t\t\"type\": \"Point\",\n\t\t\"coordinates\": [\n\t\t\tlongitude,\n\t\t\tlatitude\n\t\t]\n\t},\n\t\"name\": name,\n\t\"speed\": speed,\n\t\"cargoWeight\": cargoWeight,\n\t\"serviceStatus\": serviceStatus,\n\t\"serviceProvided\": [\n\t\tserviceProvided1,\n\t\tserviceProvided2\n\t],\n\t\"areaServed\": areaServed,\n\t\"refVehicleModel\": refVehicleModel,\n\t\"vehiclePlateIdentifier\": vehiclePlateIdentifier\n}\n",
138+
"output": "str",
139+
"x": 1610,
140+
"y": 780,
141+
"wires": [
142+
[
143+
"30dff466.fd0104"
144+
]
145+
]
146+
},
147+
{
148+
"id": "30dff466.fd0104",
149+
"type": "http response",
150+
"z": "51af8c53.929c6c",
151+
"name": "JSONata response",
152+
"statusCode": "",
153+
"headers": {
154+
"content-type": "text/plain"
155+
},
156+
"x": 1870,
157+
"y": 780,
158+
"wires": []
159+
}
160+
]
9.61 KB
Loading

json-multi-schema-resolver.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323

2424
<div class="form-row">
2525
<label for="node-input-mappingsUrl"><i class="icon-tag"></i> Mappings URL</label>
26-
<input type="text" id="node-input-mappingsUrl" placeholder="mappingsUrl" />
26+
<input type="text" id="node-input-mappingsUrl" placeholder="mappingsUrl"
27+
placeholder="https://raw.githubusercontent.com/alexandrainst/node-red-contrib-json-multi-schema/master/examples/smart-data-models.json" />
2728
</div>
2829
</script>
2930

@@ -36,7 +37,7 @@
3637
<li>The original JSON data is kept unaltered in <code>msg.payload</code></li>
3738
<li>Errors are returned on <code>msg.error</code></li>
3839
</ul>
39-
<p>Example of configuration file containing the </p>
40+
<p>Example of configuration file containing the mappings of schemas: </p>
4041
<pre>
4142
[
4243
{

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "node-red-contrib-json-multi-schema",
3-
"version": "0.3.3",
3+
"version": "0.3.4",
44
"description": "Generic JSON data pipeline tools, with dynamic transformation (using JSONata rules), resolving JSON Schema (using JSONata rules), and then validation (using JSON Schema). For Node-RED and for command-line.",
5-
"main": "index-validate.js",
5+
"main": "index.js",
66
"readmeFilename": "readme.md",
77
"keywords": [
88
"schema",

0 commit comments

Comments
 (0)