brightecapital / service-schema
Service Schema for Microservice
This package's canonical repository appears to be gone and the package has been frozen as a result.
Requires
- php: ^7.1|^8.1
- justinrainbow/json-schema: ^5.2
- psr/container: ^1.0
- psr/log: ^1.0.2
Requires (Dev)
- phpspec/prophecy: ^1.16
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^3.5
- dev-master
- 1.10.0
- 1.9.7
- 1.9.6
- 1.9.5
- 1.9.4
- 1.9.3
- 1.9.2
- 1.9.1
- 1.9.0
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.9
- 1.3.8
- 1.3.7
- 1.3.6
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.9
- 1.2.8
- 1.2.7
- 1.2.6
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.9
- 1.1.8
- 1.1.7
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-fix/move-out-uuid-package
- dev-add-logger-to-service-factory
- dev-feature/phpcs
- dev-feature/BH-5865
- dev-add-logger
- dev-feature/BH-5351-producer-plain
- dev-feature/BH-5351
- dev-version2
- dev-feature/issue#1-namespacing
- dev-fix-tests
This package is auto-updated.
Last update: 2024-09-07 01:23:08 UTC
README
Service-schema was created as a tool to process messages from broker or between microservices, implementing event sourcing and Saga pattern. Based on the concept of "event schema first", service-schema improves things a step further by introducing schema for each service in order to reuse services and schemas in different events through configuration:
- Each event might has one or many services that are listening to it
- Each service has one schema which will be used to validate the input json
Configuration
"require": { "brightecapital/service-schema": "^1.0.0" }
Sample code
configs
events.json
[ { "event": "Users.afterSaveCommit.Create", "services": [ "ServiceSchema\\Tests\\Service\\Samples\\CreateContact", "ServiceSchema\\Tests\\Service\\Samples\\CreateTask" ] }, { "event": "Users.afterSaveCommit.Update", "services": [ "ServiceSchema\\Tests\\Service\\Samples\\UpdateContact" ] } ]
In this events.json:
- There are 02 events that the microservice is listening to: "Users.afterSaveCommit.Create", "Users.afterSaveCommit.Update"
- Each of event have a list of services that listen to the event
services.json
[ { "service": "ServiceSchema\\Tests\\Service\\Samples\\CreateContact", "schema": "/jsons/schemas/CreateContact.json", "callbacks": [ "ServiceSchema\\Tests\\Service\\Samples\\PushMessageToSqs", "ServiceSchema\\Tests\\Service\\Samples\\PushMessageToLog" ] }, { "service": "ServiceSchema\\Tests\\Service\\Samples\\UpdateContact", "schema": "/jsons/schemas/UpdateContact.json", "callbacks": [ "ServiceSchema\\Tests\\Service\\Samples\\PushMessageToLog" ] }, { "service": "ServiceSchema\\Tests\\Service\\Samples\\CreateTask", "schema": "/jsons/schemas/CreateTask.json" } ]
In this services.json:
- There are 03 services: "ServiceSchema\Tests\Service\Samples\CreateContact", "ServiceSchema\Tests\Service\Samples\UpdateContact", "ServiceSchema\Tests\Service\Samples\CreateTask",
- Each service has a schema and a list of callback services
services schema
CreateContact.json
{ "type": "object", "properties": { "event": { "type": "string", "minLength": 0, "maxLength": 256 }, "time": { "type": "string", "minLength": 0, "maxLength": 256 }, "payload": { "type": "object", "properties": { "user": { "type": "object", "properties": { "data": { "type": "object" }, "class": { "type": "string", "default": "\\App\\Entity\\User" } }, "required": [ "data" ] }, "account": { "type": "object", "properties": { "data": { "type": "object" }, "class": { "type": "string", "default": "\\App\\Entity\\Account" } }, "required": [ "data" ] } }, "required": [ "user", "account" ], "additionalProperties": false } }, "required": [ "event", "payload" ], "additionalProperties": true }
In this CreateContact.json:
- It requires the message to have "name" and "payload"
- "payload" requires "user" and "account"
- "user" requires "data"
- "account" requires "data"
Event
$event = new Event(); $event->setName("Users.afterSaveCommit.Create"); $event->setTime("20190730123000"); $event->setPayload(["user" => ["data" => ["name" => "Ken"]], "account" => ["data" => ["name" => "Brighte"]]]); $message = $event->toJson(); // '{"name":"Users.afterSaveCommit.Create","time":"20190730123000","payload":{"user":{"data":{"name":"Ken"}},"account":{"data":{"name":"Brighte"}}}}' // this message is used to push to SQS or other services
Service
namespace ServiceSchema\Tests\Service\Samples; use ServiceSchema\Event\Message; use ServiceSchema\Event\MessageInterface; use ServiceSchema\Service\Service; use ServiceSchema\Service\ServiceInterface; class CreateContact extends Service implements ServiceInterface { public function consume(MessageInterface $event = null) { echo "CreateContact"; return new Message(); } }
Processor
// Receive message from SQS or other services $message = '{"name":"Users.afterSaveCommit.Create","time":"20190730123000","payload":{"user":{"data":{"name":"Ken"}},"account":{"data":{"name":"Brighte"}}}}'; // config the Processor $processor = new Processor(["events.json"], ["services.json"], "serviceSchemaDir"); // process the message $result = $processor->process($message); /* * In this example, event "Users.afterSaveCommit.Create" has 02 services listening to it (configued in events.json) * "ServiceSchema\\Tests\\Service\\Samples\\CreateContact", "ServiceSchema\\Tests\\Service\\Samples\\CreateTask" * When $processor->process(message): CreateContact->run(Event) and CreateTask->run(Event) will be executed. * Service CreateContact has 02 callback services (configured in services.json): * "ServiceSchema\\Tests\\Service\\Samples\\PushMessageToSqs","ServiceSchema\\Tests\\Service\\Samples\\PushMessageToLog" * When CreateContact->run(Event) returns an Event then PushMessageToSqs->run(Event) and PushMessageToLog->run(Event) will be executed */
UUID
Using Ramsey/Uuid to generate event id
Tests
Please refer to tests for sample configs of events, services, schemas and usage of Processor
- tests/jsons/configs/events.json: configuration of events
- tests/jsons/config/services.json: configuration of services
- tests/jsons/configs/schemas/: sample services schemas (CreateContact.json, CreateTask.json, UpdateContact.json)
- tests/Main/ProcessorTest.php: how to config and run the Processor