kleijnweb/rest-e-tag-bundle

This package is abandoned and no longer maintained. No replacement package was suggested.

Caching and Concurrency Control for REST APIs using E-Tag Headers

Installs: 128

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 2

Forks: 0

Open Issues: 1

Type:symfony-bundle

v1.0.0 2016-02-21 13:45 UTC

This package is not auto-updated.

Last update: 2024-01-15 08:27:54 UTC


README

Build Status Coverage Status Scrutinizer Code Quality Latest Stable Version

Small bundle that adds caching and Concurrency Control for REST APIs using E-Tag Headers.

Go to the release page to find details about the latest release.

For an example see swagger-bundle-example.

NOTE: Looking for PHP <7.0 and Symfony <2.8.7 support? Use a 01.x version.

Functional Details

RestETagBundle uses REST semantics to form a cache invalidation and optimistic concurrency strategy.

  • Versions the resources your URI paths represents and keeps this list in a server side cache.
  • Increments the version of a path when one of the following methods is used: POST, PUT, PATCH, DELETE
  • Increments the version of all parent and selected "lower" paths when that of a child is incremented
  • Ensures the tag passed using If-Match matches the ETag in the cache, returns HTTP 412 in case of discrepancy.
  • Returns HTTP 428 responses when concurrency control is enabled and the appropriate header is missing.

The bundle uses microtime based version IDs to prevent loss of the server side cache causing collisions and sub-second resource locking. Removes all non-printable and non-ascii chars from URLs before using them as cache keys.

The versioning scheme is pretty straightforward, examples:

  • Modifying /animals/rabbits/1: Invalidates /animals, /animals/rabbits, /animals/rabbits/1, and (if it exists) /animals/rabbits/1/relations/owners

  • GET on /animals/rabbits/2: This is not effected by the previous example. In addition, this will create a version if none exists yet (without invalidating anything)

  • Modifying /animals/rabbits: Both /animals and /animals/rabbits get a new version. So will any existing versions matching the child invalidation constraint (see configuration), eg /animals/rabbits/findByName

The query part of the URL is treated as the last path segment:

  • Modifying /animals?type=rabbits: Will be interpreted as modification of /animals/?type=rabbits. So /animals will be invalidated.

  • GET on /animals?type=rabbits: Will be interpreted as GET /animals/?type=rabbits.

  • Modifying /animals/rabbits?id=1: Will be interpreted as a modification of /animals/rabbits/?id=1. So the old versions of both /animals and /animals/rabbits are invalidated too.

  • GET on /animals?type=dogs: Will be interpreted as GET /animals/?type=dogs. So a modification of /animals?type=rabbits will not affect it (but modification of /animals will invalidate it).

The default child invalidation constraint is a negated regular expression: \/[0-9]+$. This means a POST to /animals/rabbits will by default not invalidate /animals/rabbits/1 or any paths below it, but will invalidate /animals/rabbits/findByName.

NOTE: When concurrency control is turned on, you cannot POST to without the correct E-Tag either.

NOTE: The store and retrieve calls are not yet fully optimized and get pretty chatty when using network based caches. You can probably expect best performance from APCu. It won't use that much memory.

Install And Configure

Install using composer (composer require kleijnweb/rest-e-tag-bundle). You want to check out the release page to ensure you are getting what you want and optionally verify your download.

Concurrency control is enabled by default. To disable:

rest_e_tags:
  concurrency_control: false

The bundle will work with any PSR-16 cache (networked caches are strongly discouraged). Use the 'cache' config option to reference the service to be used:

rest_e_tags:
  cache: my.cache.service

You can tweak the default child invalidation constraint (negated, see default above):

rest_e_tags:
  # Do not invalidate paths that look like they end in UUIDs (nor any paths below them)
  child_invalidation_constraint: '\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
rest_e_tags:
  # Always invalidate, skip regex match
  child_invalidation_constraint: ''

License

KleijnWeb\RestETagBundle is made available under the terms of the LGPL, version 3.0.