Example). Hal, Type Assert Middleware, Cors
$ git clone https://github.com/istyle-inc/example-hack-strict-api.git
$ hhvm -d xdebug.enable=0 -d hhvm.jit=0 -d hhvm.php7.all=1\
-d hhvm.hack.lang.auto_typecheck=0 $(which composer) install
$ curl http://example-hack-strict-api.vagrant/
Content-Type application/hal+json
{
"id": 1234,
"name": "ytake",
"title": "type-assert for api response",
"_links": {
"self": {
"href": "/",
"type": "application/json"
}
},
"_embedded": {
"enviroments": [
{
"name": "HHVM/Hack",
"_links": {
"self": {
"href": "https://docs.hhvm.com/"
}
}
},
{
"name": "zend-diactoros",
"_links": {
"self": {
"href": "https://zendframework.github.io/zend-diactoros/"
}
}
}
]
}
}
<?hh // strict
namespace App\Middleware;
use Facebook\TypeAssert;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class ResponseAssertMiddleware implements MiddlewareInterface {
const type embeddedLinks = shape(
'name' => string,
'_links' => shape(
'self' => shape(
'href' => string
)
)
);
const type hateoasStructure = shape(
'id' => int,
'name' => string,
'title' => string,
'_links' => shape(
'self' => shape(
'href' => string,
'type' => string
)
),
'_embedded' => shape(
'enviroments' => array<self::embeddedLinks>
)
);
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler,
): ResponseInterface {
$response = $handler->handle($request);
$decode = json_decode($response->getBody()->getContents(), true);
TypeAssert\matches_type_structure(
type_structure(self::class, 'hateoasStructure'),
$decode,
);
return $response;
}
}