Эта документация описывает использование базовых API-модулей `SearchApi` и `SaveApi`, предназначенных для быстрой разработки RESTful API-endpoints. Эти модули позволяют создавать, читать, обновлять и удалять (CRUD) данные с минимальным количеством кода, предоставляя гибкие механизмы для валидации, фильтрации и преобразования данных.
namespace App.Database;
use Runtime.BaseObject;
use Runtime.ORM.Record;
use Runtime.ORM.Annotations.AutoIncrement;
use Runtime.ORM.Annotations.BigIntType;
use Runtime.ORM.Annotations.Primary;
use Runtime.ORM.Annotations.StringType;
class Item extends Record
{
/**
* Returns table name
*/
pure string getTableName() => "forms";
/**
* Returns table schema
*/
pure memorize Collection<BaseObject> schema() =>
[
/* Fields */
new BigIntType{"name": "id"},
new StringType{"name": "name"},
new StringType{"name": "description"},
new BigIntType{"name": "category_id"},
new DateTimeType{"name": "gmtime_add", "autocreate": true},
new DateTimeType{"name": "gmtime_edit", "autoupdate": true},
/* Index */
new AutoIncrement{"name": "id"},
new Primary{"keys": ["id"]},
];
}Модуль `SearchApi` предоставляет базовый функционал для создания API-endpoints, предназначенных для поиска и получения данных из базы данных. Он разработан для гибкой настройки запросов и обработки результатов.
Ключевые возможности
namespace App.Api;
use Runtime.Serializer.MapType;
use Runtime.ORM.Query;
use Runtime.Web.Annotations.ApiMethod;
use Runtime.Widget.Api.SearchApi;
use Runtime.WordPress.Admin.AdminMiddleware;
use App.Database.Item;
class ItemSearchApi extends SearchApi
{
/**
* Returns api name
*/
pure string getApiName() => "app.item";
/**
* Returns record name
*/
pure string getRecordName() => classof Item;
/**
* Returns middleware
*/
Vector<Middleware> getMiddleware() =>
[
new AdminMiddleware(),
];
/**
* Returns data rules
*/
void getDataRules(MapType rules)
{
}
/**
* Returns item fields
*/
Vector<string> getItemFields() =>
[
"id",
"name"
];
/**
* Build Query
*/
async void buildQuery(Query q)
{
}
/**
* Action search
*/
@ApiMethod{ "name": "search" }
async void actionSearch()
{
await parent();
}
/**
* Action item
*/
@ApiMethod{ "name": "item" }
async void actionItem()
{
await parent();
}
}Модуль SaveApi предоставляет базовый функционал для создания API-endpoints, предназначенных для сохранения (создания и обновления) и удаления данных в базе данных. Он обеспечивает надежную валидацию данных, обработку CRUD-операций и гибкую настройку логики через систему хуков.
Ключевые возможности
Два основных действия:
Продолжая пример с сущностью Item, для создания API для сохранения и удаления товаров, мы можем определить следующий класс:
namespace App.Api;
use Runtime.Widget.Api.SaveApi;
use Runtime.Widget.Api.Rules.UniqueRule;
use Runtime.WordPress.Admin.AdminMiddleware;
use App.Database.Item;
class ItemSaveApi extends SaveApi
{
/**
* Returns api name
*/
pure string getApiName() => "app.item";
/**
* Returns record name
*/
pure string getRecordName() => classof Item;
/**
* Returns middleware
*/
Vector<Middleware> getMiddleware() =>
[
new AdminMiddleware(),
];
/**
* Returns save rules
*/
Vector<BaseRule> rules() =>
[
new UniqueRule{"field_name": "name"},
];
/**
* Returns data rules
*/
void getDataRules(MapType rules)
{
}
/**
* Returns item rules
*/
void getItemRules(MapType rules)
{
rules.addType("id", new IntegerType());
rules.addType("name", new Required());
rules.addType("name", new StringType());
rules.addType("description", new StringType());
rules.addType("category_id", new IntegerType());
}
/**
* Returns item fields
*/
Vector<string> getItemFields() =>
[
"id",
"name",
"description",
"category_id",
"gmtime_add",
"gmtime_edit",
];
/**
* Build query
*/
async void buildQuery(Query q)
{
await parent(q);
if (this.foreign_key && this.foreign_key.has("category_id"))
{
q.where("category_id", "=", this.foreign_key.get("category_id"));
}
}
/**
* Save before
*/
async void onSaveBefore()
{
await parent();
}
/**
* Save after
*/
async void onSaveAfter()
{
await parent();
}
/**
* Delete before
*/
async void onDeleteBefore()
{
await parent();
/* Запрет удаления, если есть связанные заказы */
if (this.item.get("has_orders"))
{
throw new ApiError(new RuntimeException(
"Невозможно удалить запись, так как существуют связанные заказы."
));
}
}
/**
* Delete after
*/
async void onDeleteAfter()
{
}
/**
* Save action
*/
@ApiMethod{ "name": "save" }
async void actionSave()
{
await parent();
}
/**
* Delete action
*/
@ApiMethod{ "name": "delete" }
async void actionDelete()
{
await parent();
}
}