Interface and example changes
This commit is contained in:
parent
885b81cfe9
commit
0a7557329c
@ -1,371 +0,0 @@
|
|||||||
These are 5 examples for ModelRequests on a given dataset with the expected
|
|
||||||
results. There are 6 models:
|
|
||||||
- A, B, C, D: some models with a common `title` attribute and an attribute per
|
|
||||||
model (a, b, c, d).
|
|
||||||
- G1, G2: Some models with generic relations.
|
|
||||||
|
|
||||||
Relations:
|
|
||||||
- A <-1---1-> B (B_id <-> A_id)
|
|
||||||
- A <-1---n-> C (C_ids <-> A_id)
|
|
||||||
- B <-n---m-> C (C_ids <-> B_ids)
|
|
||||||
- B <-1---n-> B selfreference modeling a tree (B_children_ids <-> B_parent_id)
|
|
||||||
- B <-n---m-> D with structured keys on D's side. The numbers are not related to
|
|
||||||
any ids. (D_ids <-> B_<number>_ids)
|
|
||||||
- G1 <-n---m-> A,C (content_object_ids <-> G1_ids)
|
|
||||||
- G2 <-1---1-> A,B (content_object_id <-> G2_id)
|
|
||||||
|
|
||||||
Notes about the value `null`: If a field is not present, its value is implicit
|
|
||||||
`null`. Fields with `null` as value are included in the ModelResponse but not
|
|
||||||
the dataset. This means, that there might be references without a reverse part in
|
|
||||||
the dataset, but this is fine, as the missing part is implicitly `null`. If a
|
|
||||||
field is deleted in the dataset, there is an update with `null` as the value of
|
|
||||||
the field.
|
|
||||||
|
|
||||||
Dataset: {
|
|
||||||
A: [{
|
|
||||||
id: 1,
|
|
||||||
a: "a1",
|
|
||||||
title: "a1",
|
|
||||||
B_id: 1,
|
|
||||||
C_ids: [],
|
|
||||||
G1_ids: [1, 2],
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
a: "a2",
|
|
||||||
title: "a2",
|
|
||||||
C_ids: [1, 2],
|
|
||||||
G1_ids: [],
|
|
||||||
}],
|
|
||||||
B: [{
|
|
||||||
id: 1,
|
|
||||||
b: "b1",
|
|
||||||
title: "b1";
|
|
||||||
A_id: 1,
|
|
||||||
C_ids: [1],
|
|
||||||
G2_id: 1,
|
|
||||||
B_children_ids: [2],
|
|
||||||
D_ids: [1],
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
b: "b2",
|
|
||||||
title: "b2",
|
|
||||||
C_ids: [1, 2],
|
|
||||||
B_parent_id: 1,
|
|
||||||
B_children_ids: [],
|
|
||||||
D_ids: [1, 2],
|
|
||||||
}],
|
|
||||||
C: [{
|
|
||||||
id: 1,
|
|
||||||
c: "c1",
|
|
||||||
title: "c1",
|
|
||||||
A_id: 2,
|
|
||||||
B_ids: [1, 2],
|
|
||||||
G1_ids: [2, 3],
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
c: "c2",
|
|
||||||
title: "c2",
|
|
||||||
A_id: 2,
|
|
||||||
B_ids: [2],
|
|
||||||
G1_ids: [2, 3],
|
|
||||||
}],
|
|
||||||
D: [{
|
|
||||||
id: 1,
|
|
||||||
d: "d1",
|
|
||||||
B_1_ids: [1, 2],
|
|
||||||
B_2_ids: [1],
|
|
||||||
B_3_ids: [],
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
d: "d2",
|
|
||||||
B_1_ids: [],
|
|
||||||
B_4_ids: [2],
|
|
||||||
}],
|
|
||||||
G1: [{
|
|
||||||
id: 1,
|
|
||||||
g1: "g1.1",
|
|
||||||
content_object_ids: ["A/1"],
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
g1: "g1.2",
|
|
||||||
content_object_ids: ["A/1", "C/1", "C/2"],
|
|
||||||
}, {
|
|
||||||
id: 3,
|
|
||||||
g1: "g1.3",
|
|
||||||
content_object_ids: ["C/1", "C/2"],
|
|
||||||
}],
|
|
||||||
G2: [{
|
|
||||||
id: 1,
|
|
||||||
g2: "g2.1",
|
|
||||||
content_object_id: "B/1",
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
I: Basic
|
|
||||||
Note:
|
|
||||||
- The basic structure
|
|
||||||
- The empty model B/1 in the response
|
|
||||||
- The provided references, e.g. A/2/C_ids in the response
|
|
||||||
|
|
||||||
ModelRequest: {
|
|
||||||
collection: "A",
|
|
||||||
ids: [1, 2],
|
|
||||||
fields: {
|
|
||||||
a: null,
|
|
||||||
C_ids: {
|
|
||||||
collection: "C",
|
|
||||||
fields: {
|
|
||||||
c: null,
|
|
||||||
G1_ids: {
|
|
||||||
collection: "G1",
|
|
||||||
fields: {
|
|
||||||
g1: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
B_id: {
|
|
||||||
collection: "B",
|
|
||||||
fields: {},
|
|
||||||
},
|
|
||||||
G1_ids: {
|
|
||||||
collection: "G1"
|
|
||||||
fields: {
|
|
||||||
g1: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ModelData: {
|
|
||||||
A: {
|
|
||||||
1: {
|
|
||||||
a: "a1",
|
|
||||||
C_ids: [],
|
|
||||||
B_id: 1,
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
a: "a2",
|
|
||||||
C_ids: [1, 2],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
B: {
|
|
||||||
1: {}
|
|
||||||
}
|
|
||||||
C: {
|
|
||||||
1: {
|
|
||||||
c: "c1",
|
|
||||||
G1_ids: [2, 3],
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
c: "c2",
|
|
||||||
G1_ids: [2, 3],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
G1: {
|
|
||||||
1: {
|
|
||||||
g1: "g1.1",
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
g1: "g1.2",
|
|
||||||
},
|
|
||||||
3: {
|
|
||||||
g1: "g1.3",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
II: Partial merged fields, generic lookup
|
|
||||||
Note:
|
|
||||||
- different fields for B/1 and B/2 in the response
|
|
||||||
- different fields for C/1 and C/2 in the response
|
|
||||||
- The generic lookup from G2/1 to B/1
|
|
||||||
|
|
||||||
ModelRequest: {
|
|
||||||
collection: "G2"
|
|
||||||
ids: [1],
|
|
||||||
fields: {
|
|
||||||
content_object_id: {
|
|
||||||
fields: {
|
|
||||||
B_children_ids: {
|
|
||||||
collection: "B",
|
|
||||||
fields: {
|
|
||||||
C_ids: {
|
|
||||||
collection: "C",
|
|
||||||
fields: {
|
|
||||||
c: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
B_parent_id: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
C_ids: {
|
|
||||||
collection: "C",
|
|
||||||
fields: {
|
|
||||||
c: null,
|
|
||||||
title: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
G2_id: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ModelData: {
|
|
||||||
B: {
|
|
||||||
1: {
|
|
||||||
B_children: [2],
|
|
||||||
C_ids: [1],
|
|
||||||
G1_id: 1,
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
C_ids: [1, 2],
|
|
||||||
B_parent_id: 1,
|
|
||||||
}
|
|
||||||
G2: {
|
|
||||||
1: {
|
|
||||||
content_object_id: "B/1",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
C: {
|
|
||||||
1: {
|
|
||||||
c: "c1",
|
|
||||||
title: "c1",
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
c: "c2",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
III: non-existent ids, fields, fqids, references, generic relations and felder ohne referenz
|
|
||||||
Note:
|
|
||||||
- id 4 of G1 does not exist
|
|
||||||
- some fields does not exist
|
|
||||||
- some fields with indicated references does not exist (fine, until there is
|
|
||||||
no data. If there is data, this will cause an parsing-error at runtime)
|
|
||||||
- All these cases are fine
|
|
||||||
|
|
||||||
ModelRequest: {
|
|
||||||
collection: "G1",
|
|
||||||
ids: [2, 4], # 4 does not exists
|
|
||||||
fields: {
|
|
||||||
content_object_ids: {
|
|
||||||
fields: {
|
|
||||||
a: null,
|
|
||||||
b: null,
|
|
||||||
not_existent: {
|
|
||||||
key: null,
|
|
||||||
},
|
|
||||||
title: null,
|
|
||||||
G1_ids: null,
|
|
||||||
A_id: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ModelData: {
|
|
||||||
G1: {
|
|
||||||
2: {
|
|
||||||
content_object_ids: ["A/1", "C/1", "C/2"],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
A: {
|
|
||||||
1: {
|
|
||||||
a: "a1",
|
|
||||||
title: "a1",
|
|
||||||
G1_ids: [1, 2],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
C: {
|
|
||||||
1: {
|
|
||||||
title: "c1",
|
|
||||||
A_id: 2,
|
|
||||||
G1_ids: [2, 3],
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
title: "c2",
|
|
||||||
A_id: 2,
|
|
||||||
G1_ids: [2, 3],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IV: structured fields without references
|
|
||||||
Note:
|
|
||||||
- `B_` is handled as a prefix
|
|
||||||
|
|
||||||
ModelRequest: {
|
|
||||||
collection: "D",
|
|
||||||
ids: [1, 2],
|
|
||||||
fields: {
|
|
||||||
d: null,
|
|
||||||
B_: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ModelData: {
|
|
||||||
D: {
|
|
||||||
1: {
|
|
||||||
d: "d1",
|
|
||||||
B_1_ids: [1, 2],
|
|
||||||
B_2_ids: [1],
|
|
||||||
B_3_ids: [],
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
d: "d2",
|
|
||||||
B_1_ids: [],
|
|
||||||
B_4_ids: [2],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
V: structed references
|
|
||||||
Note:
|
|
||||||
- `B_` and `B_4_ids` are handled as prefixes (`B_4_ids` has only one match)
|
|
||||||
- All references are followed
|
|
||||||
- The different fields for B/1 and B/2 in the response
|
|
||||||
|
|
||||||
ModelRequest: {
|
|
||||||
collection: "D",
|
|
||||||
ids: [1, 2],
|
|
||||||
fields: {
|
|
||||||
B_: {
|
|
||||||
collection: "B",
|
|
||||||
fields: {
|
|
||||||
b: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
B_4_ids: {
|
|
||||||
collection: "B",
|
|
||||||
fields: {
|
|
||||||
title: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ModelData: {
|
|
||||||
D: {
|
|
||||||
1: {
|
|
||||||
d: "d1",
|
|
||||||
B_1_ids: [1, 2],
|
|
||||||
B_2_ids: [1],
|
|
||||||
B_3_ids: [],
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
d: "d2",
|
|
||||||
B_1_ids: [],
|
|
||||||
B_4_ids: [2],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
B: {
|
|
||||||
1: {
|
|
||||||
b: "b1",
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
b: "b2",
|
|
||||||
title: "b2",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -27,56 +27,52 @@ subscribe(request: ModelRequest): stream<ModelData>;
|
|||||||
* This is the main interface for requesting models in a structured, nested way.
|
* This is the main interface for requesting models in a structured, nested way.
|
||||||
* The initial request targets some models as the root models of one collection
|
* The initial request targets some models as the root models of one collection
|
||||||
* with all the same fields. This build a tree of dependencies, because the
|
* with all the same fields. This build a tree of dependencies, because the
|
||||||
* value of some fields may be a GenericModelDescriptor again.
|
* value of some fields may be a GenericRelationFieldDescriptor again.
|
||||||
*
|
*
|
||||||
* For a description of `fields` and `collection`, see GenericModelDescriptor
|
* For a description of `fields` and `collection`, see GenericRelationFieldDescriptor
|
||||||
* and ModelDescriptor.
|
* and RelationFieldDescriptor.
|
||||||
*
|
*
|
||||||
* `ids`: This is a list of ids for a collection, that should be provided. All
|
* `ids`: This is a list of ids for a collection, that should be provided. All
|
||||||
* models, that the user can see, must be included in the response. The model
|
* models, that the user can see, must be included in the response. The model
|
||||||
* fields are handled according to `GenericModelDescriptor`.
|
* fields are handled according to `GenericRelationFieldDescriptor`.
|
||||||
*/
|
*/
|
||||||
Interface ModelRequest {
|
Interface ModelRequest extends Fields {
|
||||||
ids: ID[];
|
ids: ID[];
|
||||||
collection: Collection;
|
collection: Collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
Interface Fields {
|
||||||
fields: {
|
fields: {
|
||||||
[field: Field]: GenericModelDecriptor | null;
|
[field: Field]: GenericRelationFieldDescriptor
|
||||||
|
| RelationFieldDescriptor
|
||||||
|
| StructuredFieldDescriptor
|
||||||
|
| null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For an overview, see `ModelRequest`.
|
* For an overview, see `ModelRequest`.
|
||||||
*
|
*
|
||||||
* `fields`:
|
* `fields` (inherited from `Fields`, see above):
|
||||||
* All fields are handled as prefixes being aware of strutured fields. If a
|
|
||||||
* field is given, all fields with the given field as a prefix are included.
|
|
||||||
* E.g. if the field is `my_field`, the fields `my_field`, `my_field_3` and
|
|
||||||
* `my_fields` are included.
|
|
||||||
*
|
|
||||||
* Regardless of the value of a field, the restricted values are given in the
|
* Regardless of the value of a field, the restricted values are given in the
|
||||||
* response (multiple for structured fields). If the restricted value is null,
|
* response (multiple for structured fields). If the restricted value is null,
|
||||||
* the field must be included here.
|
* the field must be included here.
|
||||||
*
|
*
|
||||||
* Note that the fields may be empty in the request or empty after restriction.
|
|
||||||
* The client gets an empty model, but *gets* a model. Only if the model does
|
|
||||||
* not exist or the user cannot see the model, there will be no model in the
|
|
||||||
* response.
|
|
||||||
*
|
|
||||||
* If the value is not null, it is indicated, that there is a reference to
|
* If the value is not null, it is indicated, that there is a reference to
|
||||||
* follow. There are two types of values:
|
* follow. There are three types of values:
|
||||||
* - GenericModelDescriptor: The reference is a generic one. This means, that
|
* - GenericRelationFieldDescriptor: The reference is a generic one. This means, that
|
||||||
* the actual value from the model is a fqid or an array of fqids.
|
* the actual value from the model is a fqid or an array of fqids.
|
||||||
* - ModelDescriptor: A collection is given, so it can be expected, that the
|
* - RelationFieldDescriptor: A collection is given, so it can be expected, that the
|
||||||
* actual model value is an id or an array of ids.
|
* actual model value is an id or an array of ids.
|
||||||
|
* - StructuredFieldDescriptor: The field is a template field and should be
|
||||||
|
* handled in this way.
|
||||||
*/
|
*/
|
||||||
Interface GenericModelDecriptor {
|
Interface GenericRelationFieldDecriptor extends Fields {
|
||||||
fields: {
|
type: 'generic-relation' | 'generic-relation-list';
|
||||||
[field: Field]: GenericModelDecriptor | null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For an overview, see `ModelRequest`.
|
* For an overview, see `ModelRequest`. For `fields`, see GenericRelationFieldDescriptor.
|
||||||
*
|
*
|
||||||
* `collection`:
|
* `collection`:
|
||||||
* This is the collection, the ids are associated to. The ids are provided with
|
* This is the collection, the ids are associated to. The ids are provided with
|
||||||
@ -85,10 +81,41 @@ Interface GenericModelDecriptor {
|
|||||||
* - If this interface is used in a field indication a relation, the id(s) are
|
* - If this interface is used in a field indication a relation, the id(s) are
|
||||||
* given by the actual model data.
|
* given by the actual model data.
|
||||||
*/
|
*/
|
||||||
Interface ModelDescriptor extends GenericModelDescriptor {
|
Interface RelationFieldDescriptor extends Fields {
|
||||||
|
type: 'relation' | 'relation-list';
|
||||||
collection: Collection;
|
collection: Collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structured Fields: A field with `$` as a placeholder can be structured. The
|
||||||
|
* `$` is a template placeholder. The `template field` holds a list of strings
|
||||||
|
* with options to insert into `$`. All these fields are the `structured
|
||||||
|
* fields`. Example:
|
||||||
|
* B_$_ids is the template field. Its value may be `["1", "test"]`, so the
|
||||||
|
* structured fields are B_1_ids and B_test_ids.
|
||||||
|
*
|
||||||
|
* This interface indicates, that there are structured fields related to the
|
||||||
|
* given template field, that should be resolved. If one would give `B_$_ids:
|
||||||
|
* null` without using this interface, the response would be just the template
|
||||||
|
* field `B_$_ids` and no structured fields.
|
||||||
|
*
|
||||||
|
* For just resolving values, leav `values` out (hence the optional parameter).
|
||||||
|
*
|
||||||
|
* If the values of all structured fields are references, use the `values`
|
||||||
|
* parameter analog to the `fields` paramter as documented in
|
||||||
|
* `GenericRelationFieldDescriptor`.
|
||||||
|
*/
|
||||||
|
Interface StructuredFieldDecriptor extends fields {
|
||||||
|
type: 'template',
|
||||||
|
values?: {
|
||||||
|
[field: Field]: GenericRelationFieldDescriptor
|
||||||
|
| RelationFieldDescriptor
|
||||||
|
| StructuredFieldDescriptor
|
||||||
|
| null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure holds all data given by the called service structured by
|
* This structure holds all data given by the called service structured by
|
||||||
* fqids. Each fqid contains the (partial, restricted) data for the fqid.
|
* fqids. Each fqid contains the (partial, restricted) data for the fqid.
|
||||||
|
Loading…
Reference in New Issue
Block a user