{"id":20254812,"url":"https://github.com/chippyash/sdo-pattern","last_synced_at":"2025-03-03T17:18:06.791Z","repository":{"id":28823956,"uuid":"32347360","full_name":"chippyash/SDO-Pattern","owner":"chippyash","description":"Service Data Object Pattern","archived":false,"fork":false,"pushed_at":"2018-07-05T16:30:14.000Z","size":41,"stargazers_count":0,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-14T03:34:12.078Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chippyash.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-16T19:19:23.000Z","updated_at":"2022-02-09T07:13:56.000Z","dependencies_parsed_at":"2022-07-25T18:02:57.579Z","dependency_job_id":null,"html_url":"https://github.com/chippyash/SDO-Pattern","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FSDO-Pattern","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FSDO-Pattern/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FSDO-Pattern/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FSDO-Pattern/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chippyash","download_url":"https://codeload.github.com/chippyash/SDO-Pattern/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241705919,"owners_count":20006399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T10:34:59.543Z","updated_at":"2025-03-03T17:18:06.769Z","avatar_url":"https://github.com/chippyash.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chippyash/SDO-Pattern\n\n## Quality Assurance\n\n![PHP 5.6](https://img.shields.io/badge/PHP-5.6-blue.svg)\n![PHP 7](https://img.shields.io/badge/PHP-7-blue.svg)\n[![Build Status](https://travis-ci.org/chippyash/SDO-Pattern.svg?branch=master)](https://travis-ci.org/chippyash/SDO-Pattern)\n[![Test Coverage](https://codeclimate.com/github/chippyash/SDO-Pattern/badges/coverage.svg)](https://codeclimate.com/github/chippyash/SDO-Pattern/coverage)\n[![Code Climate](https://codeclimate.com/github/chippyash/SDO-Pattern/badges/gpa.svg)](https://codeclimate.com/github/chippyash/SDO-Pattern)\n\nThe above badges represent the current development branch.  As a rule, I don't push\n to GitHub unless tests, coverage and usability are acceptable.  This may not be\n true for short periods of time; on holiday, need code for some other downstream\n project etc.  If you need stable code, use a tagged version. Read 'Further Documentation'\n and 'Installation'.\n \nPlease note that the Travis build servers sometimes have a wobbly and thus the build\nstatus may be incorrect.  If you need to be certain, click on the build status badge\nand checkout out the build for yourself.\n \nSee the [Test Contract](https://github.com/chippyash/SDO-Pattern/blob/master/docs/Test-Contract.md)\n\n## What?\n\nThis library supplies the Service Data Object (SDO) pattern.  SDOs have a [long history](http://en.wikipedia.org/wiki/Service_Data_Objects) and provide a way to abstract\nout the process and operation on retrieving and sending data to some remote service endpoint.  That endpoint can\nbe a file, a database, a REST service etc.\n\nEssentially, you are not interested in where the data resides, only in using it.  The SDO pattern abstracts out the\nfetching and sending process to allow you to concentrate on using the data in some internalised format.\n\nThere is a [long discourse](http://devzone.zend.com/330/introducing-service-data-objects-for-php/) on implementing SDOs \nin PHP written by Zend that describes a much more complex SDO infrastructure than is provided in this library. Personally, \nI've never had the need to get complicated with SDOs, but it's there if you need it.\n\nThe library is released under the [GNU GPL V3 or later license](http://www.gnu.org/copyleft/gpl.html)\n\n## Why?\n\nThis pattern has emerged through many years of repeating the same thing:\n\n- I need data in a format that I can use it\n- The data is located at some endpoint over which I have no control\n\nThere are some key elements to a SDO if you ignore the complexity of session storage and potential caching of SDOs\nin flight:\n\n- You need to have a consistent internal representation of the remote data\n    - mappers provide this. The mapper turns external format data (xml, json etc) into an internal format (a model\n    class for instance) that can be referenced by the application. The mapper also maps that internal format back out\n    to the external format for writing.\n- You need to validate that the incoming remote data is conformant\n    - validators provide this\n- The remote endpoint may change over time\n    - transports facilitate this. Transports can connect to databases, file stores, http endpoints etc.\n    \n## When\n\nThe current library provides the basic tools for creating SDOs, primarily the required interfaces.  Also included\n is an abstract SDO which you can extend for your concrete implementation. Simple mappers, validators and transports are\n provided. An example script is also provided to give you a flavour of how to implement them.\n \nIf you want more, either suggest it, or better still, fork it and provide a pull request.\n\nCheck out [ZF4 Packages](http://zf4.biz/packages?utm_source=github\u0026utm_medium=web\u0026utm_campaign=blinks\u0026utm_content=sdopattern) for more packages\n \n## How\n\n### Coding Basics\n\nAn SDO requires three things in order to operate effectively:\n\n* a TransportInterface (Transport) to do the actual fetching and sending of data from and to the service endpoint\n* a MapperInterface (Mapper) to map the external data into something your application can use, and to map that internal \n representation back out as something the service endpoint understands\n* a ValidatorInterface (Validator) so that you can be assured that incoming data meets your application's requirements\n\nThe following is based on a simple scenario:\n\n- data is contained in a file that is provided by some other system over which we have no control\n    - we need a file transport\n- external data format is json, the internal format is a StdClass\n    - we need a mapper that maps incoming json to StdClass and back out as Json\n- external data needs to match a specific minimal pattern to be valid\n    - we need a validator that checks minimum requirements\n     \n#### Transport\n\nThe TransportInterface dictates two methods:\n\n- public function read();\n    - read data from a remote endpoint\n    \n- public function write($data);\n    - write data to a remote endpoint\n\nThe supplied chippyash\\SDO\\Transport\\File gives us what we need, and takes a single construction parameter, the path\nto the file.\n\n#### Mapper\n\nThe MapperInterface dictates two methods:\n\n- public function mapIn($data);\n    - map some data fetched by TransportInterface::read() into some internalised format\n    \n- public function mapOut($internal);\n    - map internal formatted data to some external format to be used by TransportInterface::write()\n    \nThe supplied chippyash\\SDO\\Mapper\\Json gives what we need.\n\n#### Validator\n\nThe ValidatorInterface dictates one method:\n\n- public function isValid($external);\n    - validate the external format data read by TransportInterface::read() and return true if valid else false.\n     \nThe chippyash\\SDO\\Validator\\Passthru validator simply returns true for any data it is asked to validate, and is used\nfor our example.\n\n#### SDO\n\nThe SDOInterface dictates\n\n- public function fetch();\n    - fetch SDO data from remote source, validate it and map it into internalised format\n- public function send();\n    - convert internal format data to external format and send it to remote target\n- public function getData();\n    - get internal format data\n- public function setData($incomingData);\n    - set the SDOs internal data structure directly\n- public function setMapper(MapperInterface $mapper);\n    - set the mapper for the SDO\n- public function setTransport(TransportInterface $transport);\n    - set the transport for the SDO\n- public function setValidator(ValidatorInterface $validator);\n    - set the validator for the SDO\n    \nFor our example we can create a simple SDO by extending the AbstractSDO and constructing it with\n\n\u003cpre\u003e\n    class FooSDO extends AbstractSDO {}\n    \n    $sdo = new FooSDO(\n        new FileTransport(__DIR__ . '/test.json'),\n        new JsonMapper(),\n        new PassthruValidator()\n    );\n\u003c/pre\u003e\n\nTo read and write data we can use:\n\n\u003cpre\u003e\n    $obj = $sdo-\u003efetch()-\u003egetData();\n    $obj-\u003ebar += 1;\n    $sdo-\u003esend();\n\u003c/pre\u003e\n\nThe AbstractSDO also supports proxying the getData() method via the magic \\__invoke method, so we can also read and write\nthus:\n\n\u003cpre\u003e\n    $sdo-\u003efetch();\n    $sdo()-\u003ebar += 1;\n    $sdo-\u003esend();\n\u003c/pre\u003e\n\nThis clearly is closer to true SDO usage.  \n\nIt is not beyond the wit of a PHP dev to create a descendent SDO that is \ntotally self managing, caching locally when required, fetching and sending only when required.  In my day job, we have \nall of this and service classes that manage whole collections of SDOs.  Numb nuts upstream change the incoming payload;\n we just change the validator (if necessary, see below). Change the endpoint; we change the transport. Want to change the way you \n represent the data internally; change the mapper.  \n \nOn Mappers, consider using the [Assembly Builder](https://github.com/chippyash/Assembly-Builder) or [Builder Pattern](https://github.com/chippyash/Builder-Pattern) if you need to create \ncomplex data structures.\n\nOn Validators, code defensively. Validate only what you expect to use and ignore the rest.  That way, when they change the\npayload without telling you, you don't care (assuming they leave what you want in it!).\nConsider using [Functional Validation](https://github.com/chippyash/Validation)\n\nYou can find the source in example/example.php.\n\n### Changing the library\n\n1.  fork it\n2.  write the test\n3.  amend it\n4.  do a pull request\n\nFound a bug you can't figure out?\n\n1.  fork it\n2.  write the test\n3.  do a pull request\n\nNB. Make sure you rebase to HEAD before your pull request\n\nAlternatively, raise a ticket in the issue tracker\n\n## Where?\n\nThe library is hosted at [Github](https://github.com/chippyash/SDO-Pattern). It is\navailable at [Packagist.org](https://packagist.org/packages/chippyash/sdo-pattern)\n\n### Installation\n\nInstall [Composer](https://getcomposer.org/)\n\n#### For production\n\nadd\n\n\u003cpre\u003e\n    \"chippyash/sdo-pattern\": \"\u003e=3,\u003c4\"\n\u003c/pre\u003e\n\nto your composer.json \"requires\" section\n\n#### For development\n\nClone this repo, and then run Composer in local repo root to pull in dependencies\n\n\u003cpre\u003e\n    git clone git@github.com:chippyash/SDO-Pattern.git chippyash-sdo\n    cd chippyash-sdo\n    composer install\n\u003c/pre\u003e\n\nTo run the tests:\n\n\u003cpre\u003e\n    cd chippyash-sdo\n    vendor/bin/phpunit -c test/phpunit.xml test/\n\u003c/pre\u003e\n## License\n\nThis software library is released under the [BSD 3 Clause license](https://opensource.org/licenses/BSD-3-Clause)\n\nThis software library is Copyright (c) 2015-2018, Ashley Kitson, UK\n\n## History\n\nV1.0.0 Original release\n\nV2.0.0 BC Break: namespace change from chippyash\\SDO to Chippyash\\SDO\n\nV2.0.1 update examples\n\nV2.0.2 Add link to packages\n\nV2.0.3 verify PHP7 compatibility\n\nV2.0.4 update build scripting\n\nV3.0.0 BC Break. Withdraw support for PHP \u003c5.6\n\nV3.1.0 Change of license from GPL V3 to BSD 3 Clause\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchippyash%2Fsdo-pattern","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchippyash%2Fsdo-pattern","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchippyash%2Fsdo-pattern/lists"}