-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: extend custom ORD content #63
Conversation
I was wondering, if we should have the custom ORD content be in sync with the ideas of a delta ORD document... |
Do you mean that we should not just have a way to add / completely override, but use the same idea of the "JSON Patch" format (with explicit I'm not entirely sure. Merging sounds better first, but it would make it really difficult to completely override something that the CAP framework generated by default. If you just want to selectively override something, you would likely use the local annotations where they belong (Service level). So we need to pick between: Merge Behavior
Override Behavior
|
I am not on the latest stage with the exact delta ORD syntax. What we observe here is that we need deep merge logic (e.g. overwrite an APIs package assignment without the need for rewriting everything). Don't we need as similar logic also for delta ORD, like overwriting just the endpoint of an API? I agree, that we need to explain the merge & overwrite logic. However, I thought, if we can sync these, we only need to describe it once |
Ok, but overwriting a package assignment should not be done on the global ORD override level. You should do it on the CDS Service Level with |
true, bad example with package assignment. but not every ORD Resource has the CDS entities, e.g. package. what should we do there. |
Let's handle the custom package assignment in #64 |
Co-authored-by: Sebastian Wennemers <sebastian.wennemers@sap.com>
Co-authored-by: Sebastian Wennemers <sebastian.wennemers@sap.com>
At the moment, I use lodash.merge as merge strategy: https://lodash.com/docs/4.17.15#merge. You can see the code. It will override existing item and merge new item if not existed. |
{ | ||
"apiProtocol": "odata-v5", | ||
"description": "new AdminService", | ||
"ordId": "sap.test.cdsrc.sample:apiResource:AdminService:v1", | ||
"entityTypeMappings": [ | ||
{ | ||
"entityTypeTargets": [ | ||
"new.entityType.target" | ||
] | ||
} | ||
] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better have a testcase, where you add a new rest API, the other API resource overrides should be handled via @ORD.Extension mechanism, see linked issue.
By default the lodash merge will not have the JSON merge patch semantics with Here is some JSFiddle that I wrote for showing how AsyncAPI trait inheritance could work: https://jsfiddle.net/FannonF/yLsonr57/latest/ function apply(origin, patch) {
if (!isObject(patch)) {
// If the patch is not an object, it replaces the origin.
return patch;
}
const result = !isObject(origin) ? // Non objects are being replaced.
{} : // Make sure we never modify the origin.
Object.assign({}, origin);
Object.keys(patch).forEach(key => {
const patchVal = patch[key];
if (patchVal === null) {
delete result[key];
} else {
result[key] = apply(result[key], patchVal);
}
});
return result;
} |
Hi @Fannon, I have some corner cases need to discuss:
{
"apiResources": [
{
"ordId": "sap.sm:apiResource:SupplierService:v1",
"partOfGroups": [
null,
"sap.cds:service:sap.test.cdsrc.sample:AdminService"
],
"partOfPackage": "sap.sm:package:smDataProducts:v1"
}
]
} I should remove the ´partOfGroups´?
{
"apiResources": [
{null},
{
"ordId": "sap.sm:apiResource:SupplierService:v1",
"partOfGroups": [
"sap.cds:service:sap.test.cdsrc.sample:AdminService"
],
"partOfPackage": "sap.sm:package:smDataProducts:v1"
}
]
} or this case: {
"apiResources": [
null
]
} |
Nice summary of corner-cases, @zongqichen . I'll answer inline below:
To keep it simple (and stick with JSON Merge patch), we should always override arrays completely. Everything else will get complicated very quickly when ordering changes. Setting
This is not even valid JSON and therefore cannot be supported :)
Same situation as with first edge-case. We'll not support it. If you want to remove the array, you need to set |
I read JSON merge patch rfc7396, I think it's slightly different with our use case. We should not always override arrays completely. If users want to update package localId for example, they need to define following content, package ordId and localId they need to update:
If we override completely, there are only two properties left. Our strategy is based on ordId, if no ordId mateched or provided, then extend it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks quite good, let's check a few comments in the sync
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zongqichen @swennemers @Fannon
Please check the comment I left.
const clonedOrdContent = structuredClone(ordContent); | ||
for (const key in customORDContent) { | ||
const propertyType = typeof customORDContent[key]; | ||
if (propertyType !== 'object' && propertyType !== 'array') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding of this check(and after @zongqichen explained me) is that we want to allow "patch" of the resulting ORD document by appending only the properties that are arrays/lists. That then can cause some confusion, because one can put property "something" of type array, and the plugin will generate a non-valid ORD Document.
Yes, Metadata Validator is the one validating it and it's main purpose, but on the other side we are this way generating "on-the-fly" a non-valid ORD Document which is to my opinion wrong.
I would rather keep the check to strictly allowed fields("dataProducts", "entityTypes") or at least add some validation on the very begging of the ORD doc generation if the custom *ord.json file contains properties with correct names(dataProducts, entityTypes...). Something like validation schema for the json object. Still, if it is already agreed among three of you to check only if the property is array, I will approved the PR.
cc: @Fannon @zongqichen @swennemers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aramovic79 , these are good comments.
One of the use cases for this overwrite as well as also the @ORD.Extension is to allow a developer being ahead of the plugins Support for ORD. If we restrict the properties, we can't add things not yet available in the plug-in. But you are right, this comes with the risk of an broken ORD document. We can mitigate the risk with the validator and in case we want to experiment with new ORD features, we might even want the chance to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I link this comment to the #65, lets fix it in the following pr.
No description provided.