Split OpenApi Paths into multiple path definition files - json

I want to split my paths (which are quite many) more easily into their own files.
Let's say I've got two major paths /user and /anotherPath with several subpaths. Now I've got an OpenApi spec file, whose paths are being referenced to an index file which holds references to each paths. Defining EVERY path with its' reference works, but is clumsy to write.
I want something like this:
openapi.json
{
...
"paths": {
"$ref": "paths/index.json"
}
...
}
paths/index.json
{
"/user": { // and everything that comes after user, e.g. /user/{userId}
"$ref": "./user-path.json"
},
"/anotherPath": { // and everything that comes after anotherPath, e.g. /anotherPath/{id}
"$ref": "./anotherPath-path.json"
}
}
paths/user-path.json
{
"/user": {
"get": {...}
},
"/user/{userId}": {
"get": {...}
}
}
paths/anotherPath-path.json
{
"/anotherPath": {
"get": {...}
},
"/anotherPath/{id}": {
"get": {...}
}
}
This way, whenever I add another path to /user or /anotherPath, I can simply edit their respective path file, e.g. paths/user-path.json.
EDIT1: Apparently, this topic is being discussed already.. For anyone interested: https://github.com/OAI/OpenAPI-Specification/issues/417 . By the way, I know that a $ref is not valid for the paths Object, but once figuring out how to properly split, this may not be necessary anymore.

OpenAPI does not have a concept of sub-paths / nested paths, each path is an individual entity. The paths keyword itself does not support $ref, only individual paths can be referenced.
Given your user-path.json and anotherPath-path.json files, the correct way to reference path definitions is as follows:
{
...
"paths": {
"/user": {
"$ref": "paths/user-path.json#/~1user" // ~1user is /user escaped according to JSON Pointer and JSON Reference rules
},
"/user/{id}": {
"$ref": "paths/user-path.json#/~1user~1%7Bid%7D" // ~1user~1%7Bid%7D is /user/{id} escaped
},
"/anotherPath": {
"$ref": "paths/anotherPath-path.json#/~1anotherPath" // ~1anotherPath is /anotherPath escaped
},
"/anotherPath/{id}": {
"$ref": "paths/anotherPath-path.json#/~1anotherPath~1%7Bid%7D" // ~1anotherPath~1%7Bid%7D is /anotherPath/{id} escaped
}
}
...
}
YAML version:
paths:
/user:
$ref: "paths/user-path.json#/~1user"
/user/{id}:
$ref: "paths/user-path.json#/~1user~1%7Bid%7D"
/anotherPath:
$ref: "paths/anotherPath-path.json#/~1anotherPath"
/anotherPath/{id}:
$ref: "paths/anotherPath-path.json#/~1anotherPath~1%7Bid%7D"
If you want to use $ref in arbitrary places (other than where OAS allows $refs), you'll have to pre-process your definition using a parser/tool that can resolve arbitrary $refs; this will give you a valid OpenAPI file that can be used with OpenAPI-compliant tools. One such pre-processing tool is json-refs, you can find an example of pre-processing here.

Related

JSON Schema / Formly dependent sub-schemas

This issue is a bit tricky to describe so bear with me and please ask questions if I am missing anything...
Say you have a json object that defines a list of features, each feature has a the same three properties but has a property that has an entirely different structure. For example:
{
features: [
{
id: "feature-a",
enabled: true,
configurationData: {
featureAConfigPropertyA: {
somePrperty: "whatever",
anotherProperty: true
},
featureAConfigPropertyB: "some string"
}
},
{
id: "feature-b",
enabled: true,
configurationData: {
featureBConfigArrayPropertyA: ["some string"],
featureBConfigPropertyB: [
{
"id": "some string",
"name": "some string",
"description": "some string",
"enabled": true
}
]
}
}
]
}
The actual structure of each feature is irrelevant. I am just trying to express this via json schema whereby the structure of configurationData for each feature is dependent on or dictated by the feature id value of its parent.
EDIT: I guess technically it doesnt need to be dependent on so long as either structure of configurationData is valid schema for that property on the feature schema itself. Also, the types in configurationData arent arbitrary, they would always be one of the two types for a given feature in this example.
This however needs to be structured in a way that can be expressed via Formly as I am using this to generate forms. In this case it would be an array of ObjectFieldTypes, one for feature a and one for feature b, which would enumerate the three properties and provide Input field types, until it got to configurationData at which point it would use an ObjectFieldType again, which would now be different for each field type.
The issue here is that 1) I'm not sure how to express this in json schema and 2) I can't use things like patternProperties with formly because the properties have to be explicitly defined in the json schema in order for formly to render the field types for each property. Although patternProperties would technically be valid schema in this case, if the schema doesn't define those properties, then the model in the valueChanges observable on the FormGroup just excludes them entirely. So I would end up with:
{
features:[
{
id: "feature-a",
enabled: true,
configurationData: { }
},
{
id: "feature-b",
enabled: true,
configurationData: { }
}
]
}
I have tried the if then else construct, but I cant tell if the schema is wrong or if formly just doesn't support this. I made a stack blitz for this below:
https://stackblitz.com/edit/angular-g45ydm?file=src%2Fassets%2Fjson-schema%2Fif_then.json

Check with jsonschema if path is valid

I am trying to write a json schema including the feature to check if a path is valid and exist.
For example I want to validate this json:
{
"paths": ["/path/to_check", "../path/not/valid", "../../path/exists"]
}
My current schema is:
{
"type": "object",
"properties": {
"paths": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
Is there a way to indicate that items must contain valid/existing paths?
You can use regex, but there's no way to determine if a path is a real path according to a file system. JSON Schema works with JSON data... that's all, nothing more. It has no notion of a file system.
I've been googling for the same thing and was coming to the same conclusion that #Relequestual posted (who is the authority on such things).
What may be of interest is that the pydantic library extends their JSON Schema with a bunch of extensions for complex string sub-types, including file-path, directory-path and path (and many, many more).
This could be useful either directly, or to adopt as a quasi-standard for a custom implementation.

Is there a way to split a Swaggerfile / OpenAPI definition into multiple files?

Is there a way to split a swaggerfile / OpenAPI specs file, either JSON or YAML, encoding every $ref into a separate file? Because I found a lot of solutions to achieve the opposite (multiple files -> single file), but none for this.
What I'd like to achieve is the following:
I have a huge JSON swaggerfile that contains internal $refs.
I'd like to have a single file for each and every object or path definition, and, in the root file, references (local or absolute) to these files. This way I can edit the root file to easily obtain a minimal subset of the paths and objects that I need.
{
"in": "inputField",
"required": true,
"schema": {
"$ref": "#/components/schemas/MyObject"
},
"components": {
"schemas": {
"MyObject": {
"type": "object",
"properties": {
"value": {
"type": "string"
}
}
}
}
},
"____comment": "I want MyObject definition in MyObject.json file and the $ref to that file"
}
Yeah, its possible, you must only use regex, and detect depedencies etc.
regex example from my project
new Regex("\"#/definitions/(.*)\"");
new Regex("#\\/definitions\\/(.*?)\\\"");
new Regex("\"" + key + "\": ");
etc.
You must replace elements with dependencies, and save to file. I do sth like that to recive jschema from model. Your case,is a little diffrent, but smilar.

AMP Analytics "destinationDomains" not working in Linker config

I am trying to enable a linker string for links to my domains from my AMP site.
The current config is working only for links to the "canonical" domain at present, which is the default behavior.
I am also trying to enable it for links that are sent to my app's domain.
I've tried many variations of the code below (including using non-valid JSON array strings, as set out in the documentation here: https://ampbyexample.com/advanced/joining_analytics_sessions/#destination-domains) however this does not seem to work.
I am hoping this is a syntax or config issue but I am starting to have doubts. This is my code:
<amp-analytics type="gtag" data-credentials="include">
<script type="application/json">
{
"vars": {
"gtag_id": "AW-XXXXXX",
"config": {
"UA-XXXXX-X": {
"groups": "default"
},
"AW-XXXXXX": {
"groups": "default"
}
}
},
"linkers": {
"enabled": true,
"proxyOnly": false,
"destinationDomains": [ "amp.mydomain.com", "www.mydomain.com", "app.altdomain.ly" ]
},
"triggers": {
"trackPageview": {
"on": "visible",
"request": "pageview"
}
}
}
</script>
</amp-analytics>
I've also tried setting it out with a nested <paramName> object as follows, but I get the same result (works on canonical only):
...
"linkers": {
"Linker1": {
"ids": {
"_cid": "CLIENT_ID"
},
"proxyOnly": false,
"destinationDomains": [ "amp.mydomain.com", "www.mydomain.com", "app.altdomain.ly" ],
"enabled": true
}
}
...
Since you are using gtag, I think you might need to use the GTAG's configuration to configure the domains. Instructions are available here.
Basically, the config looks like this:
<amp-analytics type="gtag" data-credentials="include">
<script type="application/json">
{
"vars" : {
"gtag_id": "<GA_TRACKING_ID>",
"config" : {
"<GA_TRACKING_ID>": {
"groups": "default",
"linker": { "domains": ["example.com", "example2.com"] }
}
}
}
}
</script>
</amp-analytics>
You can check first the proper format of linkers in AMP:
"linkers": {
<paramName>: {
ids: <Object>,
proxyOnly: <boolean>,
destinationDomains: <Array<string>>,
enabled: <boolean>
}
}
paramName - This user defined name determines the name of the query
parameter appended to the links.
ids - An object containing key-value pairs that is partially encoded
and passed along in the param.
proxyOnly - (optional) Flag indicating whether the links should only
be appended on pages served on a proxy origin. Defaults to true.
destinationDomains - (optional) Links will be decorated if their
domains are included in this array. Defaults to canonical and source
domains.
enabled - Publishers must explicity set this to true to opt-in to
using this feature.
This linker uses this configuration to generate a string in this structure: <paramName>=<version>*<checkSum>*<idName1>*<idValue1>*<idName2>*<idValue2>... For more details see Linker Param Format.

extract from a JSON array (JMeter)

what is the best approach to capture from the following array?
i only need to capture the value of ANY 'beginDate', e.g: 2017-05-01T08:30:00 could be a valid one in below example
i need to make sure the 'beschikbaar' = TRUE for the date that i'm capturing
i tried using json path extractor with similar lines: $..[?(#.beschikbaar == 'true')].beginDate but i'm facing syntax errors that i cant fix due to my limited regex/json path knowledge
the example array is;
{
"data":
[
[
{
"beginDate":"2017-05-01T08:00:00",
"eindDate":null,
"beschikbaar":false
},
{
"beginDate":"2017-05-01T08:15:00",
"eindDate":null,
"beschikbaar":false
},
{
"beginDate":"2017-05-01T08:30:00",
"eindDate":"2017-05-01T10:30:00+02:00",
"beschikbaar":true
},
{
"beginDate":"2017-05-01T08:45:00",
"eindDate":"2017-05-01T10:45:00+02:00",
"beschikbaar":true
},
{
"beginDate":"2017-05-01T09:00:00",
"eindDate":"2017-05-01T11:00:00+02:00",
"beschikbaar":true
},
{
"beginDate":"2017-05-01T09:15:00",
"eindDate":"2017-05-01T11:15:00+02:00",
"beschikbaar":true
},
{
"beginDate":"2017-05-01T09:30:00",
"eindDate":"2017-05-01T11:30:00+02:00",
"beschikbaar":true
},
{
"beginDate":"2017-05-01T09:45:00",
"eindDate":"2017-05-01T11:45:00+02:00",
"beschikbaar":true
},
{
"beginDate":"2017-05-01T10:00:00",
"eindDate":"2017-05-01T12:00:00+02:00",
"beschikbaar":true
},
Don't use regular expressions for JSON data, JMeter provides JSON Extractor designed to work with JSON data via JSON Path Language so you should be able to get your "beginDate" with the query like:
$..[?(#.beschikbaar == true)].beginDate
Demo:
Check out JMeter's JSON Path Extractor Plugin - Advanced Usage Scenarios article for more detailed explanation and few more examples.
You can try this
(?s)\{.*?\"beginDate\":\"([^{]*?)\"[^{]+\"beschikbaar\":true.*?\}
(?s) is single-line modifier which makes . match the line break
You can test it at http://www.regexplanet.com/advanced/java/index.html
And set Template to $1$ means using the first group