Getting Started

Create your first entity with full CRUD operations, UI layouts, and permissions

This guide will walk you through creating your first entity using the Vyuh Entity System. We'll build a simple Product entity with full CRUD operations and automatic UI generation.

Prerequisites

Before starting, ensure you have:

  1. A Flutter project with Vyuh Framework set up
  2. The vyuh_entity_system package added to your dependencies
  3. Basic understanding of Flutter and Dart

Step 1: Define Your Entity Model

First, create your entity model by extending EntityBase:

lib/models/product.dart
import 'package:json_annotation/json_annotation.dart';
import 'package:vyuh_core/vyuh_core.dart';
import 'package:vyuh_entity_system/vyuh_entity_system.dart';

part 'product.g.dart';

@JsonSerializable()
class Product extends EntityBase {
  static const schemaType = 'inventory.products';

  static final typeDescriptor = TypeDescriptor(
    schemaType: schemaType,
    title: 'Product',
    fromJson: Product.fromJson,
  );

  final String name;
  final String description;
  final double price;
  final int stockQuantity;

  Product({
    required super.id,
    required this.name,
    required this.description,
    required this.price,
    required this.stockQuantity,
    super.createdAt,
    super.layout,
    super.modifiers,
  }) : super(schemaType: Product.schemaType);

  factory Product.fromJson(Map<String, dynamic> json) =>
      _$ProductFromJson(json);

  @override
  Map<String, dynamic> toJson() => _$ProductToJson(this);
}

Step 2: Generate JSON Serialization

Run the build runner to generate serialization code:

flutter pub run build_runner build --delete-conflicting-outputs

Step 3: Create the Entity API

Implement the API class for server communication:

lib/api/product_api.dart
import 'package:vyuh_entity_system/vyuh_entity_system.dart';
import '../models/product.dart';

class ProductApi extends EntityApi<Product> {
  ProductApi() : super(endpoint: '/api/products');

  @override
  Product fromJson(Map<String, dynamic> json) => Product.fromJson(json);
}

That's it! The base EntityApi class handles all CRUD operations. You only need to provide the endpoint and JSON deserialization.

Step 4: Define Layouts

Create a simple table layout for displaying your products:

lib/layouts/product_layouts.dart
import 'package:flutter/material.dart';
import 'package:vyuh_entity_system_ui/vyuh_entity_system_ui.dart';
import '../models/product.dart';

final productLayouts = EntityLayoutDescriptor<Product>(
  list: [
    TableListLayout<Product>(
      identifier: 'table',
      title: 'Table',
      icon: Icons.table_chart,
      description: 'Products in table format',
      columns: [
        EntityTableColumn<Product>(
          field: 'name',
          label: 'Name',
          cellBuilder: (context, product) => Text(product.name),
          width: 0.3,
        ),
        EntityTableColumn<Product>(
          field: 'price',
          label: 'Price',
          cellBuilder: (context, product) =>
              Text('\$${product.price.toStringAsFixed(2)}'),
          width: 0.2,
        ),
        EntityTableColumn<Product>(
          field: 'stockQuantity',
          label: 'Stock',
          cellBuilder: (context, product) => Text('${product.stockQuantity}'),
          width: 0.2,
        ),
      ],
    ),
  ],
);

Step 5: Create the Form

Define a simple form for creating and editing products:

lib/forms/product_form.dart
import 'package:vyuh_feature_forms/vyuh_feature_forms.dart' as vf;

vf.Form buildProductForm([String? entityId]) {
  return vf.Form(
    title: 'Product Form',
    description: 'Fill in the product details',
    items: [
      vf.TextField(
        name: 'name',
        label: 'Product Name',
        isRequired: true,
      ),
      vf.TextField(
        name: 'description',
        label: 'Description',
        isRequired: true,
        maxLines: 3,
      ),
      vf.TextField(
        name: 'price',
        label: 'Price',
        isRequired: true,
        keyboardType: vf.FieldKeyboardType.decimal,
      ),
      vf.TextField(
        name: 'stockQuantity',
        label: 'Stock Quantity',
        isRequired: true,
        keyboardType: vf.FieldKeyboardType.number,
      ),
    ],
  );
}

Step 6: Configure the Entity

Bring everything together in the entity configuration:

lib/config/product_config.dart
import 'package:flutter/material.dart';
import 'package:vyuh_entity_system/vyuh_entity_system.dart';
import 'package:vyuh_entity_system_ui/vyuh_entity_system_ui.dart';
import '../models/product.dart';
import '../api/product_api.dart';
import '../layouts/product_layouts.dart';
import '../forms/product_form.dart';

final productConfig = EntityConfiguration<Product>(
  metadata: EntityMetadata(
    identifier: 'products',
    name: 'Product',
    pluralName: 'Products',
    description: 'Manage your product catalog',
    icon: Icons.inventory,
  ),
  routing: EntityRoutingDescriptor(
    path: NavigationPathBuilder.collection('products', prefix: '/inventory'),
    builder: StandardRouteBuilder<Product>(),
    permissions: const EntityRoutePermissions(
      list: ['inventory.products.view'],
      create: ['inventory.products.create'],
      view: ['inventory.products.view'],
      edit: ['inventory.products.edit'],
    ),
  ),
  api: ProductApi(),
  layouts: productLayouts,
  form: EntityFormDescriptor<Product>(
    getForm: buildProductForm,
    transformer: DefaultEntityTransformer<Product>(
      fromJson: Product.fromJson,
    ),
  ),
  actions: EntityActionsDescriptor<Product>(
    inline: EntityActions.defaultsWithArchive<Product>(),
  ),
);

Step 7: Register the Entity

Register your entity with the Entity System:

lib/feature.dart
import 'package:flutter/material.dart';
import 'package:vyuh_core/vyuh_core.dart';
import 'package:vyuh_entity_system_ui/vyuh_entity_system_ui.dart';
import 'package:vyuh_extension_content/vyuh_extension_content.dart';
import 'config/product_config.dart';
import 'layouts/details/product_detail_layout.dart';
import 'models/product.dart';

final inventoryFeature = FeatureDescriptor(
  name: 'inventory',
  title: 'Inventory Management',
  description: 'Product inventory features',
  icon: Icons.inventory,
  extensions: [
    EntityExtensionDescriptor(
      entities: [
        EntityRegistration<Product>(
          productConfig,
          ContentBuilder(
            content: Product.typeDescriptor,
            defaultLayout: ProductDetailLayout(),
            defaultLayoutDescriptor: ProductDetailLayout.typeDescriptor,
          ),
        ),
      ],
    ),
  ],
);

Add the feature to your app:

lib/main.dart
import 'package:vyuh_core/vyuh_core.dart' as vc;
import 'feature.dart';

void main() {
  vc.runApp(
    initialLocation: '/',
    features: () => [
      inventoryFeature,
      // ... other features
    ],
  );
}

Step 8: Use Your Entity

Your entity is now ready to use! The entity system automatically provides:

Routes

  • /products - List all products
  • /products/new - Create new product
  • /products/:id - View product details
  • /products/:id/edit - Edit product

Access your entity through the dashboard or use the command palette (Cmd/Ctrl+K) to search for "Products".

Programmatic Access

// In your widgets
final provider = EntityProvider.of<Product>(context);

// List products
final products = await provider.list();

// Get single product
final product = await provider.byId('product-id');

// Create product
final newProduct = await provider.create(product);

// Update product
await provider.update('product-id', updatedProduct);

// Delete product
await provider.delete('product-id');

What's Next?

Congratulations! You've created your first entity with:

  • ✅ Full CRUD operations automatically generated
  • ✅ Table layout for listing products
  • ✅ Form with validation
  • ✅ Automatic routing and navigation
  • ✅ Permission-based access control

Learn More

On this page