Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/src/CanEmitJsonDefaults.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Twirp;

interface CanEmitJsonDefaults
{
public function setEmitJsonDefaults(bool $emitDefaults): void;

public function shouldEmitJsonDefaults(): bool;
}
42 changes: 39 additions & 3 deletions protoc-gen-twirp_php/templates/service/Server.php.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Twirp\BaseServerHooks;
use Twirp\CanEmitJsonDefaults;
use Twirp\Context;
use Twirp\ErrorCode;
use Twirp\ServerHooks;
Expand All @@ -23,7 +24,7 @@ use Twirp\ServerHooks;
*
* Generated from protobuf service <code>{{ .Service.Desc.FullName }}</code>
*/
final class {{ .Service | phpServiceName .File }}Server implements RequestHandlerInterface
final class {{ .Service | phpServiceName .File }}Server implements RequestHandlerInterface, CanEmitJsonDefaults
{
/**
* A convenience constant that may identify URL paths.
Expand Down Expand Up @@ -60,12 +61,18 @@ final class {{ .Service | phpServiceName .File }}Server implements RequestHandle
*/
private $prefix;

/**
* @var bool
*/
private $emitDefaults = false;

public function __construct(
{{ .Service | phpServiceName .File }} $svc,
?ServerHooks $hook = null,
?ResponseFactoryInterface $responseFactory = null,
?StreamFactoryInterface $streamFactory = null,
string $prefix = '/twirp'
string $prefix = '/twirp',
bool $emitDefaults = false
) {
if ($hook === null) {
$hook = new BaseServerHooks();
Expand All @@ -84,6 +91,7 @@ final class {{ .Service | phpServiceName .File }}Server implements RequestHandle
$this->responseFactory = $responseFactory;
$this->streamFactory = $streamFactory;
$this->prefix = rtrim($prefix, '/');
$this->setEmitJsonDefaults($emitDefaults);
}

/**
Expand Down Expand Up @@ -198,7 +206,11 @@ final class {{ .Service | phpServiceName .File }}Server implements RequestHandle
return $this->writeError($ctx, $e);
}

$data = $out->serializeToJsonString();
if ($this->shouldEmitJsonDefaults()) {
$data = $out->serializeToJsonString(\Google\Protobuf\PrintOptions::EMIT_DEFAULTS);
} else {
$data = $out->serializeToJsonString();
}

$body = $this->streamFactory->createStream($data);

Expand Down Expand Up @@ -372,4 +384,28 @@ final class {{ .Service | phpServiceName .File }}Server implements RequestHandle
// so anyway.
}
}

/**
* By default, protobuf will filter out default values from your return value.
* This changes that behavior to always emit default values, allowing for clearer
* responses for non-generated or customized clients.
* Only supported on versions greater than 4.33.0 of the protobuf package or extension.
* Will be a noop if on older versions.
*
* When false (default): `{myVal: 0, myStr: "hi"}` -> `{myStr: "hi"}`
* When true: `{myVal: 0, myStr: "hi"}` -> `{myVal: 0, myStr: "hi"}`
*/
public function setEmitJsonDefaults(bool $emitDefaults): void
{
$this->emitDefaults = $emitDefaults;
}

public function shouldEmitJsonDefaults(): bool
{
if (!defined('Google\\Protobuf\\PrintOptions::EMIT_DEFAULTS')) {
return false;
}

return $this->emitDefaults;
}
}
Loading