Getting Started

Usage

Search, mutate, delete and actions with laravel_rest_api_flutter.

Usage

Once your ItemRepository is configured, you can use it throughout your app.


final repository = ItemRepository();

Future<void> fetchItems() async {
  final response = await repository.search(
    filters: [
      Filter(field: "name", type: "contains", value: "Test"),
    ],
  );

  if (response.isSuccessful) {
    print(response.body); // Filtered items
  } else {
    print('Error: \${response.statusCode}');
  }
}

You may also pass other search options:

  • filters
  • sorts
  • includes
  • selects
  • aggregates
  • pagination options (page, limit, etc.)

🧬 Mutations (Create / Update)

Create and update items using the mutate API:

final newItem = ItemModel(id: 3, name: "New Item");

await repository.mutate(
  body: LaravelRestApiMutateBody(
    mutate: [
      // Create an item
      Mutation(
        operation: MutationOperation.create,
        attributes: newItem.toJson(),
      ),
      // Update an item
      Mutation(
        operation: MutationOperation.update,
        key: 3,
        attributes: {"name": "Updated Name"},
      ),
    ],
  ),
);

🗑️ Delete

Delete one or multiple resources (IDs or UUIDs):

await repository.delete(
  resourceIds: [5, 6],
);

⚙️ Custom Actions

Use actions for domain-specific operations defined on the Laravel side (e.g., activate, archive, expire):

await repository.actions(
  data: LaravelRestApiActionsBody(
    fields: [
      Action(name: "expires_at", value: "2023-04-29"),
    ],
  ),
);

Example Response

{
  "data": [
    { "id": 1, "name": "Lou West" },
    { "id": 2, "name": "Bridget Wilderman" }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 3,
    "total": 50
  }
}

Error example:

{
  "message": "Server error",
  "exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException"
}

Tests & Examples

test('Search items by name filter', () async {
  final itemRepository = ItemRepository();

  final result = await itemRepository.search(
    filters: [
      Filter(field: 'name', type: 'contains', value: 'Hammer'),
    ],
  );

  expect(result.statusCode, 200);
  expect(result.data, isNotNull, reason: result.message);
});

test('Delete items by IDs', () async {
  final itemRepository = ItemRepository();

  final result = await itemRepository.delete(resourceIds: [5, 6]);

  expect(result.statusCode, 200);
  expect(result.data, isNotNull, reason: result.message);
});

test('Create a new item via mutate', () async {
  final itemRepository = ItemRepository();
  final newItem = ItemModel(id: 10, name: 'New Test Item');

  final result = await itemRepository.mutate(
    body: LaravelRestApiMutateBody(
      mutate: [
        Mutation(
          operation: MutationOperation.create,
          attributes: newItem.toJson(),
        ),
      ],
    ),
  );

  expect(result.statusCode, 200);
  expect(result.data?.created.contains(10), true);
});

test('Update an existing item via mutate', () async {
  final itemRepository = ItemRepository();

  final result = await itemRepository.mutate(
    body: LaravelRestApiMutateBody(
      mutate: [
        Mutation(
          operation: MutationOperation.update,
          key: 10,
          attributes: {'name': 'Updated Test Item'},
        ),
      ],
    ),
  );

  expect(result.statusCode, 200);
  expect(result.data?.updated.contains(10), true);
});

test('Perform a custom action on items', () async {
  final itemRepository = ItemRepository();

  final result = await itemRepository.actions(
    data: LaravelRestApiActionsBody(
      fields: [
        Action(name: 'activate', value: 'true'),
      ],
    ),
  );

  expect(result.statusCode, 200);
  expect(result.data, greaterThanOrEqualTo(1));
});