Skip to content

Commit

Permalink
Updated service to support multiple types
Browse files Browse the repository at this point in the history
Added support for callable, EndpointHandler, and class name to the input for the handler function to allow for greater flexibility
  • Loading branch information
EmilJimenez21 committed Sep 16, 2024
1 parent 3bb277b commit 6880473
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 23 deletions.
40 changes: 26 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,39 +304,51 @@ $stream->put('mailer.bye', $payload);
The services feature provides a simple way to create microservices that leverage NATS.

In the example below, you will see an example of creating an index function for the posts microservice. The request can
be accessed under "v1.posts.index". You can add multiple endpoints to support your service.
be accessed under "v1.posts" and then individual post by "v1.posts.{post_id}".
```php
// Define a service
$service = $client->service('PostsService', 'This service is responsible for handling all things post related.', '1.0');
$service = $client->service(
'PostsService',
'This service is responsible for handling all things post related.',
'1.0'
);

// Create the version group
$version = $service->addGroup('v1');

// Create the service group
$posts = $version->addGroup('posts')

// Create the endpoint handler
class IndexPosts implements \Basis\Nats\Service\ServiceHandler {
// Create the index posts endpoint handler
class IndexPosts implements \Basis\Nats\Service\EndpointHandler {

public function handle(\Basis\Nats\Message\Payload $payload): array
{
// Your application logic
return [
'hello' => 'world'
'posts' => []
];
}
}

// Create an endpoint
// Create the index endpoint
$version->addEndpoint("posts", IndexPosts::class);

// Create the service group
$posts = $version->addGroup('posts');

// View post endpoint
$posts->addEndpoint(
'index',
new IndexPosts()
'*',
function (\Basis\Nats\Message\Payload $payload) {
$postId = explode('.', $payload->subject);
$postId = $postId[count($postId)-1];

return [
'post' => []
];
}
);

// Run the service
while (true) {
$client->process();
}
$service->run();
```


Expand Down
14 changes: 13 additions & 1 deletion src/Service/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public function addGroup(string $name): ServiceGroup

public function addEndpoint(
string $name,
EndpointHandler $endpointHandler,
string|EndpointHandler|callable $endpointHandler,
array $options = []
): void {
$subject = $name;
Expand Down Expand Up @@ -203,4 +203,16 @@ private function controlSubject(string $verb, string $name, string $id): string

return "\$SRV.$verb.$name.$id";
}

public function run() : void
{
print_r("$this->name is ready to accept connections\n");
while(true) {
try {
$this->client->process();
} catch (\Exception $e) {
print_r("$this->name encountered an error:\n" . $e->getMessage() . "\n");
}
}
}
}
36 changes: 29 additions & 7 deletions src/Service/ServiceEndpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ class ServiceEndpoint
private Client|Queue $subscription;

public function __construct(
private readonly Service $service,
private readonly string $name,
private readonly string $subject,
private readonly EndpointHandler $endpointHandler,
private readonly string $queue_group = 'q'
private readonly Service $service,
private readonly string $name,
private readonly string $subject,
private $endpointHandler,
private readonly string $queue_group = 'q'
)
{
$this->subscription = $this->service->client->subscribeQueue(
Expand All @@ -36,8 +36,30 @@ function (Payload $message) {
// Update the endpoint metrics
$this->num_requests += 1;

// Run the handler
$response = $this->endpointHandler->handle($message);
// Setup the response
$response = "";

switch ($this->endpointHandler) {
case is_string($this->endpointHandler):
// Instantiate the endpointHandler
$handler = new $this->endpointHandler();

// Check to make sure that the class implements ServiceEndpoint
if (!($handler instanceof EndpointHandler)) {
throw new \LogicException("Class must implement EndpointHandler");
}

$response = $handler->handle($message);
break;
case is_callable($this->endpointHandler):
$func = $this->endpointHandler;

$response = $func($message);
break;
case $this->endpointHandler instanceof EndpointHandler:
$response = $this->endpointHandler->handle($message);
break;
}

// Add to the total processing time
$this->processing_time += microtime(true) - $start;
Expand Down
2 changes: 1 addition & 1 deletion src/Service/ServiceGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function addGroup(string $name): ServiceGroup

public function addEndpoint(
string $name,
EndpointHandler $serviceHandler,
string|EndpointHandler|callable $serviceHandler,
array $options = []
): void
{
Expand Down

0 comments on commit 6880473

Please sign in to comment.