eclipse-emfcloud / emfcloud-modelserver

Modelserver component
Other
43 stars 21 forks source link

API V2: Properly define and support multi-resources patches/operations #159

Closed CamilleLetavernier closed 2 years ago

CamilleLetavernier commented 2 years ago

Follow-up issue for #150 (Model Server API V2)

Json Patch typically applies on a single object graph (the current document). However, with EMF, we may have multiple resources in the same resource set, and changes may apply to several of them at the same time.

We need to define how we can reference these resources in Patch operations, and how Json Patch are dispatched to listeners. Currently, we used non-standard Json Patch Path attributes in Json Patch Operations: resource-id#emf-id/featureName. However, this won't work with automatically-generated Json Patches.

Once the Patch/Command has been applied, we also need to notify all the model listeners, for all affected resources. Currently, we only send notifications for the main resource (as identified by the ?modeluri parameter).

CamilleLetavernier commented 2 years ago

For "pure Json Patches", I think we should remove the Resource URI from the Operation. These Json Patches should only affect one resource, corresponding to the ?modeluri parameter. So instead of our custom Json Patch:

PATCH ...models?modeluri=mymodel
BODY { op: "replace", path:"mymodel#object/name", value: "New Name" }

We'd have:

PATCH ...models?modeluri=mymodel
BODY { op: "replace", path:"path/to/object/name", value: "New Name" }

Which is a standard Json Patch. In general, if the path includes a # symbol, we can treat it as resourceURI#path, and if it doesn't, we can use the ?modeluri parameter as the Resource URI, and treat the path as a standard Json Path.

For notifications, we have two cases:

{
   data: {
      message: "OK",
      patch: [{ op: "replace", path: "path/to/object/feature", value: "New value"}]
   }
}

With:

{
   data: {
      message: "OK",
      patches: {
          "file:/firstModel.xmi": [{ op: "replace", path: "path/to/object/feature", value: "New value"}],
          "file:/secondModel.model": [{ op: "replace", path: "path/to/other/object/feature", value: "Another value"}]
      }
   }
}

(Note: this map-format could also be used during edition, for patching multiple resources in a single request/transaction).

CamilleLetavernier commented 2 years ago

Fixed with https://github.com/eclipse-emfcloud/emfcloud-modelserver/pull/217 and https://github.com/eclipse-emfcloud/emfcloud-modelserver-theia/pull/107