Download the PHP package zero-to-prod/service-model without Composer
On this page you can find all versions of the php package zero-to-prod/service-model. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download zero-to-prod/service-model
More information about zero-to-prod/service-model
Files in zero-to-prod/service-model
Package service-model
Short Description A modern approach to extensible, typesafe DTOs with factory support.
License MIT
Homepage https://github.com/zero-to-prod/service-models
Informations about the package service-model
Service Models
Contents
- Introduction
- Requirements
- Features
- Installation
- Documentation Publishing
- Automatic Documentation Publishing
- Usage
- Setting Up Your Model
- Accessing Type Safe Properties
- Factory Support
- Basic Implementation
- Native Object Support
- Enums
- Classes
- Simple Class Casting
- Using a Class Method for Parsing
- One-to-many Class Casting
- Value Casting
- One-to-many Casting
- Plugins
- Factories
- Extending the
ServiceModelTrait - Mapping
- Renaming
- Mapping Nested Properties
- Validation
- Using the
StrictTrait - Manually Validating
- Using the
- Lifecycle Hooks
- Caching
- Resource Support
- Build Your Own Resource Transformer
- Upgrading to v2
- Local Development
- Contributing
Introduction
A modern approach to typesafe Data Transfer Objects (DTOs) with factory support.
This zero-dependency package provides a serialize data into typesafe DTOs.
In the Extract Transform Load (ETL) process, this package assist in the Transformation of data into a model.
Requirements
- PHP 8.1 or higher.
Features
- Simple: Use the
ServiceModeltrait to automatically map your data. - Custom Type Casting: Define your own value casters for infinite control.
- Plugin Architecture: Build your own plugins with PHP Attributes.
- Nested Relationships: Easily define one-to-many relationships with native PHP attributes.
- Mapping: Rename and map your data how you please.
- Validation: Control when required properties are validated.
- Factory Support: Use the
factory()method to make a DTO with default values. - Native Object Support: Enums and Classes, with no extra steps.
- Resource Support: Transform you ServiceModel to an associative array with snake_case keys or implement your own.
- Fast: Designed with performance in mind.
Installation
If upgrading from v1, see the upgrade guide.
Install Zerotoprod\ServiceModel via Composer:
This will add the package to your project's dependencies and create an autoloader entry for it.
Documentation Publishing
You can publish this README to your local documentation directory.
This can be useful for providing documentation for AI agents.
This can be done using the included script:
Automatic Documentation Publishing
You can automatically publish documentation by adding the following to your composer.json:
Use the ServiceModel trait in your model.
Add properties to your model that match the keys of your data.
Pass an associative array or json string to the make() method of your model.
Use the factory() method to make a new model with default values.
See the Factories section for more information.
Usage
Create a ServiceModel by passing an associative array or json string to the make() method of
your model that uses the ServiceModel trait.
Setting Up Your Model
Define properties in your class to match the keys of your data.
The ServiceModel trait will automatically match the keys, detect the type, and cast the value.
Pass an associative array or json string to the make() method of your model.
Accessing Type Safe Properties
Access your data with arrow syntax.
Factory Support
Use the factory() method to make a new model instance with default values.
See the Factories section for how to set up and use factories.
Basic Implementation
Define properties in your class to match the keys of your data.
The ServiceModel trait will automatically match the keys, detect the type, and cast the value.
IMPORTANT: Use the
ServiceModeltrait in the child classes.NOTICE: The
detailskey matches the$detailsproperty inOrder.
Native Object Support
This package provides native support for the following objects:
- Enums
- Classes
Enums
Use a value backed enum to automatically cast the value.
Classes
Sometimes you may want to cast to a class you cannot use the ServiceModel trait in.
For a simple cast, simply typehint with the property with the class. This will automatically unpack the array into the constructor of the class.
For a one-to-many cast, use the CastToArray attribute to cast an array of classes.
Simple Class Casting
Simply typehint with the property with the class you want to cast to.
Using a Class Method for Parsing
In some cases, you might have a class with a method that accepts a value and returns an instance of the class itself.
The ServiceModel package allows you to leverage such methods for parsing values.
You can specify the method to be used for parsing by applying the CastUsing attribute to the property in your model.
The attribute takes the name of the method as its argument.
Here's an example:
In the TimeClass below, the set method accepts a value, assigns it to the value property of a new TimeClass
instance, and then returns the instance:
In this exampleWhen the ServiceModel trait processes the time property of the MyModel, it will invoke
the set method of the TimeClass, passing the value to be parsed. The method will return a TimeClass instance,
which will then be assigned to the time property.
One-to-many Class Casting
Sometimes you may want to cast an array of classes you cannot use the ServiceModel trait in.
Use the ArrayOf attribute to cast an array of classes.
Value Casting
Implement the CanCast interface to make a custom type.
One-to-many Casting
Use the CastToArray attribute to cast an array of classes.
IMPORTANT: The class name passed in the Attribute (
View::class) is passed in the constructor of theCollectionOfclass.IMPORTANT: Don't forget to add
#[Attribute]to the top of your class.
Plugins
You can define your own attributes to extend the functionality of the ServiceModel trait.
The property values are passed to the parse() method of the attribute.
The Attribute values are passed to the constructor of the attribute.
Factories
Factories provide a convenient way to generate DTOs with default values.
- Use the
ServiceModeland theHasFactorytrait in your model. - Create a class that
extendstheFactoryclass for your factory. - Set the
public string $model =property in your factory pointing to your model. - Set the
public static string $factory =property in your model pointing to your factory. - Return your default values as an array in the
definition()method in your factory.
Extending the ServiceModel Trait
You can extend the ServiceModel trait and add your own functionality to your models.
This allows you to access custom methods on the model.
Mapping
The #[MapFrom] attribute allows you to associate a property from a DTO (Data Transfer Object) with another property that possesses a different name.
This association is achievable using either a "dot" notation property name or an index.
Renaming
The following example shows how to rename a property using the #[MapFrom] attribute.
Mapping Nested Properties
The following example shows how to map a nested property using the #[MapFrom] attribute.
Validation
Sometimes you want to know if required properties are initialized on your model. Validating your model will
throw the Zerotoprod\ServiceModel\Exceptions\ValidationException if required properties are uninitialized.
There are two ways to validate your model.
- Use the
Stricttrait in your model. - Or validate manually after making your model:
Model::make()->validate().
Using the Strict Trait
When the Strict trait is used, the ServiceModel trait will throw an exception if the model is missing a required
property.
You can mix and match the Service Models that uses the Strict trait. Validation will only be called on the class that
uses that trait.
Manually Validating
You can call the validate() method on your model to manually validate your model.
Lifecycle Hooks
Use the afterMake() method to run code after the model is instantiated.
The $attributes parameter is the value passed to the make() method.
Caching
The ServiceModel trait in this project uses an in-memory caching mechanism to improve performance. The caching is
implemented using a Singleton pattern, which ensures that only a single instance of the cache is created and used
throughout the application.
The caching mechanism is used in the constructor of the ServiceModel trait. When an object is constructed, the trait
checks if a ReflectionClass instance for the current class already exists in the cache. If it doesn't, a
new ReflectionClass instance is created and stored in the cache.
The cache is also used when processing the properties of the object. For each property, the trait checks if
a ReflectionProperty instance and the property type name are already stored in the cache. If they aren't, they are
retrieved using reflection and stored in the cache.
Resource Support
Sometimes you want to convert the case of your key to snake_case.
You can do this by adding the #[MapOutputNames(ToSnakeCase::class)] attribute to your model and using
the toResource() method.
Build Your Own Resource Transformer
You can build your own resource transformer by doing this implementing the CanParse interface.
The $values parameter is the value of the object typecast as an array.
You can add this to the top of your model like this:
When you call the toResource() method, it will use your custom resource transformer.
Upgrading to v2
This guide will help you upgrade your existing codebase to use the new features and improvements in the latest version of the Service Models package
-
Update the Package
- Update Attribute Namespaces
The namespaces for the attributes have changed. Update your import statements to reflect these changes:
IMPORTANT: The namespace for attributes have moved from
Zerotoprod\ServiceModeltoZerotoprod\ServiceModel\Attributes.
Before:
After:
- Update Caster Interface
The CanCast interface has been replaced with CanParse. Update your classes that implement this interface:
IMPORTANT: The
CanCastinterface has been replaced withCanParse. Before:
After:
- Update Caster Method Names
The method names in classes implementing the caster interface have changed from set to parse. Update these methods
in your classes:
IMPORTANT: The
setmethod has been replaced withparse.
Before:
After:
Before:
After:
Please test your application thoroughly after making these changes to ensure everything works as expected.
Contributing
Contributions, issues, and feature requests are welcome! Feel free to check the issues page if you want to contribute.
- Fork the repository.
- Create a new branch (
git checkout -b feature-branch). - Commit changes (
git commit -m 'Add some feature'). - Push to the branch (
git push origin feature-branch). - Create a new Pull Request.