Backand - use own db row id as primary key - backand

Is it possible to specify your own row ID in backand objects? I want to form one-to-one relationsships in database, where I have two objects: userPrivateData and userProfile
I would like to use the id of Backands own internal user object as primary key for both objects. So basically a userId. The reason for this: With REST api you can access single items with GET /1/objects/{name}/{id}
Since I don't know the row id I want to use another unique identiefier as primary key, that I know - my user id.
Is this possible? Maybe I have the concept all wrong, in their docs they talk a lot about one-to-many relationships and stuff, but not about one-to-one relationships.

I think your JSON model would look something like this.
[
{
"name": "items",
"fields": {
"name": {
"type": "string"
},
"description": {
"type": "text"
},
"user": {
"object": "users"
}
}
},
{
"name": "users",
"fields": {
"items": {
"collection": "items",
"via": "user"
},
"allofuserprivatedata": {
"collection": "userPrivateDataThings",
"via": "userId"
},
"email": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"userProfile": {
"object": "userProfile"
}
}
},
{
"name": "userProfile",
"fields": {
"userid": {
"collection": "users",
"via": "userProfile"
},
"fieldOne": {
"type": "string"
},
"fieldTwo": {
"type": "boolean"
}
}
},
{
"name": "userPrivateDataThings",
"fields": {
"field1": {
"type": "string"
},
"field2": {
"type": "float"
},
"userId": {
"object": "users"
}
}
}
]
Use a collection when you want 1 to many.
Use an object when you want 1 to 1.
When you do a GET on user with deep:true the nested relationship data will come back in the response.

Related

Certain relations are added to the product entity for no reason

I have been using OroCommerce's API for creating products through POST requests. The request works fine but I have one problem once the entity has been created. For some reason, OroCommerce will add extra relations to the product entity.
For example, if I create a product with the name "testt", the request will have the following data :
{
"data": {
"type": "products",
"attributes": {
...
},
"relationships": {
"data": [
{
"type": "productnames",
"id": "name"
}
]
}
},
"included": [
{
"type": "productnames",
"id": "name",
"attributes": {
"fallback": null,
"string": "testt"
},
"relationships": {
"localization": {
"data": null
}
}
},
...
]
}
But when I send the POST request, the resulting entity I get has 2 name relationships instead of one, here's what the data of the resulting entity looks like with a GET request and including names :
"included": [
{
"type": "productnames",
"id": "450",
"attributes": {
"string": null,
"fallback": "system"
},
"relationships": {
"product": {
"data": {
"type": "products",
"id": "445"
}
},
"localization": {
"data": {
"type": "localizations",
"id": "1"
}
}
}
},
{
"type": "productnames",
"id": "451",
"attributes": {
"string": "testt",
"fallback": null
},
"relationships": {
"product": {
"data": {
"type": "products",
"id": "445"
}
},
"localization": {
"data": null
}
}
},
...
]
As you can see, the resulting object has an extra name relationship, even though it was never in the initial POST request to start with. I have the same issue with descriptions, shortDescriptions, where a relation with empty data gets created even if I explicitly set the data to null in the POST request.
Is there a way to prevent this?
The case is that every localizable field MUST have a value for every localization and one by default.
Such entities as
productnames
productdescriptions
productshortdescriptions
localizedfallbackvalues
can contain either a string value or fallback link to the default value or some other localization.
As is seen from your examples you have only one localization so when you create a product with
{
"type": "productnames",
"id": "name",
"attributes": {
"fallback": null,
"string": "testt"
},
"relationships": {
"localization": {
"data": null
}
}
}
the system creates a "productnames" instance with a string value inside as a default value
{
"type": "productnames",
"id": "451",
"attributes": {
"string": "testt",
"fallback": null
},
"relationships": {
"product": {
"data": {
"type": "products",
"id": "445"
}
},
"localization": {
"data": null
}
}
}
and then automatically adds "productnames" instances for each localization with fallback links (in your case one instance)
{
"type": "productnames",
"id": "450",
"attributes": {
"string": null,
"fallback": "system"
},
"relationships": {
"product": {
"data": {
"type": "products",
"id": "445"
}
},
"localization": {
"data": {
"type": "localizations",
"id": "1"
}
}
}
}
An absence of localizable field default value in a POST body will trigger "Not Null constraint".
So as detailed above every localizable field MUST has a value (or fallback) for each localization. So every time a product or localization entity is created system adds a linking entity for every intersection of every localizable field and every localization.

JSON Schema switch object properties based on enum

I've been struggling with "switch" in JSON Schema. Went through couple of GitHub and SO discussions on this topic but haven't find solution.
My intention is to vary "payload" object properties based on "id" enum that will have 30 different mappings ("payload" definitions per enum "id").
For example first message json object will have amount and other properties but for the demo purpose let's go only with one property (amout):
{
"message": {
"id": 1,
"correlationId": "a0011e83-280e-4085-b0f1-691059aaae61",
"payload": {
"amount": 100
}
}
}
And second json:
{
"message": {
"id": 2,
"correlationId": "a0011e83-280e-4085-b0f1-691059aaae61",
"payload": {
"code": "xyz"
}
}
}
Is there a way to build JSON Schema (draft 7 or any other) in this manner?
What you're asking for is a fairly common requirement. Using oneOf/anyOf should get you where you want.
In those cases where the alternatives are mutually exclusive (due to the different "id" values), I'm in favour of anyOf to allow Schema Validator to stop checking when encountering the first matching subschema – whereas oneOf implies that all other alternatives must not match, e.g. in case of "id": 1 a validator would only have to check against the first subschema in an anyOf to indicate that it is valid while for oneOf it'd have to check against the other 29 to ensure that those aren't also valid. But you may find oneOf more expressive for human consumers of your schema.
For your particular scenario, I'd imagine something along the lines of the following schema:
{
"type": "object",
"required": ["message"],
"properties": {
"message": {
"type": "object",
"required": ["id", "correlationId", "payload"],
"properties": {
"id": { "enum": [1, 2, 3] },
"correlationId": { "type": "string" },
"payload": { "type": "object" }
},
"anyOf": [
{
"properties": {
"id": { "const": 1 },
"payload": { "$ref": "#/definitions/payload1" }
}
},
{
"properties": {
"id": { "const": 2 },
"payload": { "$ref": "#/definitions/payload2" }
}
},
{
"properties": {
"id": { "const": 3 },
"payload": { "$ref": "#/definitions/payload3" }
}
},
]
}
},
"definitions": {
"payload1": {
"type": "object",
"required": ["amount"],
"properties": {
"amount": { "type": "integer" }
}
},
"payload2": {
"type": "object",
"required": ["code"],
"properties": {
"code": { "type": "string" }
}
},
"payload3": {
"type": "object",
"required": ["foo"],
"properties": {
"foo": { "type": "string" }
}
}
}
}

json schema - field is required based on another field value

I'm working on creating a JsonSchema(v4).
I'm trying to make one property required based off the value of another property from it's parent.
Parent
User
subtype
address
Child
Address
line1
line2
companyName (required if user subtype is company)
How could this be done?
I have something like this now...
{
"User": {
"title": "User",
"type": "object",
"id": "#User",
"properties": {
"subtype": {
"type": "string"
},
"address": {
"$ref": "Address"
}
}
}
"Address": {
"title": "Address",
"type": "object",
"id": "#Address",
"properties": {
"line1": {
"type": "string"
},
"line2": {
"type": "string"
},
"companyName": {
"type": "string"
}
},
"required": ["line1", "line2"]
}
}
Subtype is a arbitrary string, so a full list of the different subtypes is not possible.
Add this to your User schema. Essentially it reads as: either "subtype" is not "company" or "address" requires "companyName".
"anyOf": [
{
"not": {
"properties": {
"subtype": { "enum": ["company"] }
}
}
},
{
"properties": {
"address": {
"required": ["companyName"]
}
}
}
]

json schema object property constraints

In my schema I have an array of phone objects. Each object has a "status" property, which can be one of three values: "Primary", "Active" and "Not-in-use".
I want to set the following constraint:
If the number of phone objects > 0 then exactly one must have status="Primary"
Is this possible with json schema? If so, how?
This schema is pretty close to what you want. The only restriction is that the "Primary" phone number needs to be the first item in the array.
You might be able to get "Primary" to be anywhere in the array with some creative use of not. I'll update the answer if I figure it out.
{
"type": "object",
"properties": {
"phoneNumbers": {
"type": "array",
"items": [{ "$ref": "#/definitions/primaryPhone" }],
"additionalItems": { "$ref": "#/definitions/additionalPhone" }
}
},
"definitions": {
"phone": {
"type": "object",
"properties": {
"label": { "type": "string" },
"number": { "type": "string" }
},
"required": ["label", "number", "status"]
},
"primaryPhone": {
"allOf": [{ "$ref": "#/definitions/phone" }],
"properties": {
"status": { "enum": ["Primary"] }
}
},
"additionalPhone": {
"allOf": [{ "$ref": "#/definitions/phone" }],
"properties": {
"status": { "enum": ["Active", "Not-in-use"] }
}
}
}
}

Ember Data JSON-API hasMany: How?

I'm familiar with the old ember-data "sideloading" model, which would look like this:
```
{
authors:[
{id:1, name:"Ernest", type: 'author', books: [1,2]
],
books: [
{id:1, name: "For whom the bell tolls", type: 'book', author:1},
{id:2, name: "Farewell To Arms", type: 'book', author:1}
]
}
But the new JSON-API method is different.
For one thing, (and I like this), attributes are separated from the id and type information, preventing namespace collisions.
I don't yet understand how to do a hasMany relationship with the JSON-API format. Can anyone point me to a doc or article on how this is expected? The examples on the JSON-API page show individual relationships, but not hasMany.
If you could write the above example in the new format, you'd have answered my question.
I found the answer in The JSON-API spec.
Each model should have a relationships key, whose value is an object with a key for each named relationship, which also has a data key that can be either a single object or an array for a hasMany relationship.
By providing an included key as top-level member, I can lazy load the entities.
In this case, the above example would be:
{
"data": [
{
"id": 1,
"type": "author",
"attributes": {
"name": "Ernest"
},
"relationships": {
"books": {
"data": [
{
"id": "1",
"type": "book"
},
{
"id": "2",
"type": "book"
}
]
}
}
}
],
"included": [
{
"id": 1,
"type": "book",
"attributes": {
"name": "For Whom the Bell Tolls"
},
"relationships": {
"author": {
"data": {
"id": 1,
"type": "author"
}
}
}
},
{
"id": 2,
"type": "book",
"attributes": {
"name": "Farewell to Arms"
},
"relationships": {
"author": {
"data": {
"id": 1,
"type": "author"
}
}
}
}
]
}
FYI: If you want to fetch a hashMany relationship at a later time, you have two other options.
1. Use a Related Resource Link:
As soon as the hashMany relationship is needed, Ember Data will call the backend with related link to fetch all the relations.
{
"data": [{
...,
"relationships": {
"books": {
"links" {
"related": "http://example.com/books"
}
}
}
}]
}
2. Use find-ids
As soon as the hashMany relationship is needed, Ember Data will call the backend with an url to fetch given ids. In this example it would be http://example.com/books?ids=1&ids=2
{
"data": [{
...,
"relationships": {
"books": {
"books": {
"data" [{
"id": "1",
"type": "book"
}, {
"id": "2",
"type": "book"
}]
}
}
}
}]
}