Drupal 8 API first

Some code examples

Custom resources

                    
namespace Drupal\my_module\Plugin\rest\resource;

/**
 * @RestResource(
 *   id = "module_my_resource",
 *   label = @Translation("My sexy REST resource"),
 *   uri_paths = {
 *     "canonical" = "/api/my-endpoint/{id}",
 *     "https://www.drupal.org/link-relations/create" = "/api/my-endpoint"
 *   }
 * )
 */
 class CustomRestResource extends ResourceBase {

    public function get($id){ ... }

    public function post($data){ ... }

    public function put($data){ ... }
 }
                    
            

Caching?

Combination of 3 mechanisms:

  • Cache max-age: For time-sensitive caching, i.e. time dependencies
  • Cache context: For variations, i.e. dependencies on the user context
  • Cache tags: For dependencies on data managed by Drupal, like entities & configuration

Custom authentication provider

                    
services:
  my_module.authentication.my_auth_provider:
    class: Drupal\my_module\Authentication\Provider\MyAuthenticationProvider
    arguments:
      - '@entity_type.manager'
    tags:
      - { name: authentication_provider, provider_id: oauth2, priority: 35 }
                    
            

Custom authentication provider

                    
class MyAuthenticationProvider implements AuthenticationProviderInterface {

  /**
   * Checks whether suitable authentication credentials are on the request.
   *
   * @return bool
   *   TRUE if authentication credentials suitable for this provider are on the
   *   request, FALSE otherwise.
   */
  public function applies(Request $request){ ... };

  /**
   * Authenticates the user.
   *
   * @param \Symfony\Component\HttpFoundation\Request|null $request
   *
   * @return \Drupal\Core\Session\AccountInterface|null
   */
  public function authenticate(Request $request){ ... };

}
                    
            

Custom format

                    
services:
  my_module.encoder.my_custom_format:
    class: Drupal\my_module\Encoder\CustomFormatEncoder
    tags:
      - { name: encoder, format: custom_format }
                    
            

Custom format

                    
class CustomFormatEncoder implements SerializerAwareInterface, EncoderInterface, DecoderInterface {

  /**
   * Gets the base encoder instance.
   */
  public function getBaseEncoder() {
    return new MyCustomEncoder();
  }

  /**
   * {@inheritdoc}
   */
  public function encode($data, $format, array $context = []) {
    return $this->getBaseEncoder()->encode($data, $format, $context);
  }

  /**
   * {@inheritdoc}
   */
  public function decode($data, $format, array $context = []) {
    return $this->getBaseEncoder()->decode($data, $format, $context);
  }
}