I cannot for the life of me figure out how to create a custom "hello world" type service with 8.x. I've tried copying and modifying some of the files in services/src/Plugin/ServiceDefinition into mymodule/src/Plugin/ServiceDefinition, but it doesn't seem to do anything. I would have expected to see my custom service show up on admin/structure/service_endpoint/[my_endpoint]/resources but it's not there. How do I achieve this?

Comments

MKorostoff created an issue.

Gravypower’s picture

Hey MKorostoff,

I had the same problem, after looking into how the resources page is built I had to make sure the namespace was correct on my Service Definition. Not sure if this is the issue you are having but thought it was worth mentioning.

Aaron

MKorostoff’s picture

@Gravypower care to share your code?

Gravypower’s picture

I put together an example for you


namespace Drupal\test_module\Plugin\ServiceDefinition;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\services\ServiceDefinitionBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\SerializerInterface;

/**
 * @ServiceDefinition(
 *   id = "test_service_definition",
 *   methods = {
 *     "Get"
 *   },
 *   title = @Translation("Test Service"),
 *   description = @Translation("Test Service"),
 *   category = @Translation("Test Service"),
 *   path = "test"
 * )
 */
class TestService extends ServiceDefinitionBase implements ContainerFactoryPluginInterface {

  protected $backendCache;

  /**
   * Processes the request and returns an array of data as appropriate.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match object.
   * @param \Symfony\Component\Serializer\SerializerInterface $serializer
   *   The serializer. Some methods might require the plugin to leverage the
   *   serializer after extracting the request contents.
   *
   * @return array
   *   The response.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\HttpException
   */
  public function processRequest(Request $request, RouteMatchInterface $route_match, SerializerInterface $serializer)
  {

    return array(
      'name'=> 'TestService',
      'body' => 'hello world'
    );
  }

  /**
   * Creates an instance of the plugin.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The container to pull out services used in the plugin.
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin ID for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   *
   * @return static
   *   Returns an instance of this plugin.
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition)
  {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('cache.rest_events')
    );
  }


  public function __construct(array $configuration, $plugin_id, $plugin_definition, CacheBackendInterface $backendCache)
  {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->backendCache = $backendCache;
  }

}

I then use Postman (a chrome extension) to test the service, the only thing you need to do is make sure you send the header "Accept:application/json" with the request or the service module will not respond. You can also use the Postman with xdebug with the Postman Interceptor extension this will send any cookies you have set in the browser on your target domain with the request.