Создание сущностей
Entities API позволяет создавать сущности с помощью выполнения запроса POST
к операции (endpoint) /entities/:entityName
.
Создать сущность
Тело запроса содержит объект JSON с атрибутами сущности.
Атрибуты из черт сущностей, такие как id или createdBy , не должны добавляться в запрос. Jmix автоматически добавляет эти атрибуты при сохранении сущности.
|
Когда сущность успешно создана, возвращается код состояния HTTP 201 - Created
. По умолчанию возвращается представление метаданных сущности в формате JSON, в основном содержащее только что созданный атрибут id
для дальнейшего использования.
POST http://localhost:8080/rest/entities/sample_Customer
{
name: "Randall Bishop"
}
{
"_entityName": "sample_Customer",
"_instanceName": "Randall Bishop",
"id": "78e7996d-8b69-6526-8e9f-16262a1c4113"
}
В качестве альтернативы можно определить, какие атрибуты должны быть возвращены после создания объекта. Это можно сделать с помощью параметра URL-запроса responseFetchPlan
.
Например, URL /entities/sample_Order?responseFetchPlan=order-with-details
будет возвращать полный заказ Order со всеми его деталями, включая строки заказа, ссылки на клиентов и т. д.
Заголовок ответа HTTP Location также указывает URL-адрес созданного экземпляра сущности для дальнейших операций (таких как извлечение, обновление или удаление).
|
Валидация сущности
При создании или обновлении сущности активна и применяется обычная валидация сущности по умолчанию. Это означает, что недопустимый ввод (в соответствии с аннотациями валидации сущности) из API отклоняется с кодом состояния HTTP 400 - Bad Request
в ответе.
API возвращает подробные сообщения об ошибках для каждого нарушения валидации в форме массива JSON, показанной ниже. Каждая запись имеет следующую структуру:
- message
-
(переведенное) удобочитаемое сообщение об ошибке валидации
- messageTemplate
-
неинтерполированное сообщение об ошибке для данного нарушения ограничения
- path
-
имя атрибута (или путь к свойству), вызвавшего нарушение
- invalidValue
-
значение, которое было частью запроса атрибута, вызывающего нарушение
Следующий запрос содержит две ошибки в запросе, так как 1. требуется атрибут customer
и 2. дата date
не может быть в будущем.
POST http://localhost:8080/rest/entities/sample_Order
{
"date": "2048-01-01",
"amount": 49.99,
"customer": null
}
Затем API возвращает список нарушений валидации сущности.
[
{
"message": "javax.validation.constraints.PastOrPresent.message",
"messageTemplate": "{javax.validation.constraints.PastOrPresent.message}",
"path": "date",
"invalidValue": "2048-01-01"
},
{
"message": "may not be null",
"messageTemplate": "{javax.validation.constraints.NotNull.message}",
"path": "customer",
"invalidValue": null
}
]
Атрибуты ассоциации
Если создаваемая сущность должна быть связана с другой существующей сущностью, в запросе необходимо указать ссылку на нужную сущность.
Возьмем предыдущий пример с заказом (Order). Вам нужно сослаться на Customer через атрибут customer
при создании Order. Это делается с помощью объекта JSON, содержащего только идентификатор существующей сущности. Jmix выполнит поиск по customer по предоставленному идентификатору из запроса JSON и свяжет Customer с новым Order.
POST http://localhost:8080/rest/entities/sample_Order
{
"customer": {
"id": "f88597ff-009d-1cf2-4a90-a4fb5b08d835"
},
"date": "2021-03-01",
"amount": 130.08
}
Для всех видов ассоциаций 1:N
, N:1
, M:N
ссылки на другие сущности всегда осуществляются через их идентификатор.
Во втором примере показано, как связать Product
с несколькими сущностями ProductTag
через отношение M:N
, как описано в определении сущности Product.
@JmixEntity
@Table(name = "SAMPLE_PRODUCT")
@Entity(name = "sample_Product")
public class Product {
@JoinTable(name = "SAMPLE_PRODUCT_PRODUCT_TAG_LINK",
joinColumns = @JoinColumn(name = "PRODUCT_ID"),
inverseJoinColumns = @JoinColumn(name = "PRODUCT_TAG_ID"))
@ManyToMany
private List<ProductTag> tags;
// ...
}
В запросе экземпляры сущностей ProductTag
являются ссылками по идентификаторам. В этот раз объект JSON помещается в массив, так как есть несколько тегов продукта для ссылки.
M:N
referencesPOST http://localhost:8080/rest/entities/sample_Product?responseFetchPlan=product-with-tags
{
"name": "123",
"price": 99.95,
"tags": [
{
"id": "333f3a20-c47b-4bc9-ba34-a72d2d815695" (1)
},
{
"id": "c4c028f0-fec1-7512-83cd-c17537d1f502"
}
]
}
{
"id": "f0e04748-dcdf-d856-2482-2904f2126fcc",
"price": 99.95,
"name": "123",
"tags": [
{
"id": "333f3a20-c47b-4bc9-ba34-a72d2d815695", (2)
"name": "shiny"
},
{
"id": "c4c028f0-fec1-7512-83cd-c17537d1f502",
"name": "great"
}
]
}
1 | Ссылки на теги выполнены как список объектов JSON, содержащих идентификатор уже существующей ProductTag . |
2 | Ответ содержит сохраненную ассоциацию с двумя сущностями ProductTag . |
Атрибуты композиции
Ситуация с атрибутами, помеченными как @Composition
, несколько иная. Поскольку этот тип отношения указывает, что дочерние сущности существуют только как часть родительской, становится возможно создавать их напрямую как часть запроса на создание родительской сущности.
В следующем примере OrderLine
является дочерней сущностью Order
. Это выражается через аннотацию @Composition
атрибута lines
сущности Order
.
public class Order {
@JmixGeneratedValue
@Column(name = "ID", nullable = false)
@Id
private UUID id;
@Composition
@OneToMany(mappedBy = "order")
private List<OrderLine> lines;
// ...
}
При создании Order через API можно создавать его строки напрямую как часть запроса. В этом случае необходимо предоставить все атрибуты дочерней сущности. Отношение от родительского к дочернему элементу не нуждаются в дополнительных ссылках. Чтобы установить связь, достаточно поместить дочернюю сущность в массив JSON.
Следующий запрос JSON создаст заказ Order со строками заказа:
POST http://localhost:8080/rest/entities/sample_Order
{
"customer": {
"id": "f88597ff-009d-1cf2-4a90-a4fb5b08d835"
},
"date": "2021-03-01",
"amount": 130.08,
"lines": [ (1)
{
"quantity": 2,
"product": {
"id": "7750adbe-6c30-cede-31a6-577a1a96aa83" (2)
}
},
{
"quantity": 1,
"product": {
"code": "1ed85c7a-89f1-c339-a738-16307ed6003a"
}
}
]
}
1 | Строки заказа создаются как массив объектов JSON, содержащий все атрибуты сущности. |
2 | В случае, если дочерней сущности необходимо сослаться на другую сущность (например, ссылку N:1 с OrderLine на Product ), применяются те же правила связи через содержащий идентификатор объект JSON. |
Массовое создание
Create Entity API позволяет также создавать несколько сущностей в одном запросе. Для этого тело запроса JSON должно содержать массив объектов JSON, представляющих каждую сущность.
POST http://localhost:8080/rest
/entities
/sample_Customer
[
{
"name": "Randall Bishop"
},
{
"name": "Sarah Doogle"
}
]
[
{
"id": "c5fea05d-9062-6ac8-e9b1-7051616de102"
},
{
"id": "4a6a3aa0-ecf5-dcf4-7b37-a268a4cd3720"
}
]
В случае нарушения валидации, сущности не будут созданы, и будет возвращено соответствующее сообщение об ошибке. Подробнее см. в разделе Валидация сущности.