Overview
I created a custom REST resource by following the instructions below.
https://www.drupal.org/docs/drupal-apis/restful-web-services-api/custom-rest-resources
By following the above article, I was able to obtain a JSON result from the following URL.
/demo_rest_api/demo_resource
{
"message": "Hello, this is a rest service"
}
REST UI Module
The above article included the following note:
If you are using the REST UI contrib module, you should now be able to see it in the list of available endpoints and you should be able to configure the GET method.
For this, I enabled the REST UI module by referring to the following article.
https://www.studio-umi.jp/blog/12/357
Prototyping the IIIF Presentation API
Next, I worked on creating JSON for each content item. Specifically, I configured it so that accessing the path /iiif/3/{id}/manifest would output information based on the IIIF Presentation API v3.
The following article was helpful.
Create a file as follows. In this example, the title is retrieved from $node. By extending this approach, information from other fields can also be retrieved.
<?php
namespace Drupal\demo_rest_api\Plugin\rest\resource;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
/**
* Annotation for get method
*
* @RestResource(
* id = "iiif_presentation_3",
* label = @Translation("IIIF Presentation API v3"),
* uri_paths = {
* "canonical" = "/iiif/3/{id}/manifest"
* }
* )
*/
class Presentation3 extends ResourceBase {
/**
* Responds to GET requests. It will return serialize json format of node
* object.
*
* @param $id
* Node id.
*/
public function get($id) {
if ($id) {
// Load node
$node = Node::load($id);
if ($node instanceof NodeInterface) {
$manifest = [
"@context" => "http://iiif.io/api/presentation/3/context.json",
"type" => "Manifest",
"label" => [
"none" => [
$node->get("title")[0]->get("value")->getValue()
]
]
];
$response = new ResourceResponse($manifest);
// Configure caching for results
if ($response instanceof CacheableResponseInterface) {
$response->addCacheableDependency($node);
}
return $response;
}
return new ResourceResponse('Article doesn\'t exist', 400);
}
return new ResourceResponse('Article Id is required', 400);
}
}
Granting Permissions
On the following page, check the box for Anonymous user to allow access from external sources.
/admin/people/permissions#module-rest

As a result, by accessing a URL like /iiif/3/5070/manifest, even non-logged-in users can retrieve a JSON file like the following.
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"type": "Manifest",
"label": {
"none": [
"中村覚"
]
}
}
Summary
I introduced an example of creating custom REST resources in Drupal. I hope this serves as a reference when creating custom resources.
I also plan to continue implementing the IIIF Presentation API and create a module similar to Omeka S’s IIIF Server.