NAME

API::Docker::Role::Entity - The client reference an entity delegates through

VERSION

version 0.004

SYNOPSIS

package API::Docker::Role::Entity::Container;
use Moo::Role;
with 'API::Docker::Role::Entity';
requires 'id';
use API::Docker::Type::ContainerSummary;
use namespace::clean;

sub start {
  my ($self) = @_;
  return $self->client->containers->start($self->id);
}

# at the bottom of the same file: the methods land on the generated class
Moo::Role->apply_roles_to_package(
  'API::Docker::Type::ContainerSummary', __PACKAGE__);

DESCRIPTION

An entity is a generated API::Docker::Type class that has been given the convenience methods of its resource -- $container->start, $container->logs, $image->remove. The methods live in a role that is applied to the generated class at load time; they are never written into the generated file.

Why the methods are not in the generated class

They cannot be. maint/spec-to-type.pl --verify renders every class under lib/API/Docker/Type/ out of spec/v1.51.yaml and requires the result to match what is shipped byte for byte (t/spec_to_type.t), and the generator refuses to overwrite a file that exists. A hand-added with line or method in one of those files fails the suite; there is no mode of the generator that would put it back.

Why a role, and not a class that contains the type object

Because the daemon answers GET /containers/json and GET /containers/{id}/json with two different definitions, which are two different generated classes -- API::Docker::Type::ContainerSummary and API::Docker::Type::ContainerInspectResponse. Both need the same methods.

A wrapper class holding a type object would be a second model beside the generated one: every field access would have to be forwarded, and $container->state would return either the wrapper's idea of a state or the type object's, depending on which one the caller happened to hold. Composing a role into both generated classes leaves exactly one model. $docker->containers->list hands back real API::Docker::Type::ContainerSummary objects, TO_JSON still produces the daemon's own spelling, and the methods are written once.

Applying the role to each object instead (apply_roles_to_object) would also work and was rejected: it reblesses every entity into a generated subclass, which costs something per object and makes ref report a name no documentation mentions.

What this role contributes

The half every entity shares: the client the methods delegate through. The resource-specific methods are in a role per resource, which composes this one.

client

The API::Docker client, held as a weak_ref -- the client owns the resource classes, which produce the entities, so a strong reference here would close the cycle.

Being weak, it is undef as soon as nothing else holds the client: API::Docker->new->containers->list returns entities whose client has already gone, and the first delegating call on one of them dies. Keep the client in a live variable.

SEE ALSO

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/p5-api-docker/issues.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <getty@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.