kleijnweb / rest-e-tag-bundle
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
Requires
- php: >=5.4.0
- doctrine/cache: ^1.5.4
- psr/log: 1.0
- symfony/config: >=2.6.0
- symfony/dependency-injection: >=2.6.0
- symfony/event-dispatcher: >=2.6.0
- symfony/filesystem: >=2.6.0
- symfony/http-foundation: >=2.6.0
- symfony/http-kernel: >=2.6.0
- symfony/yaml: >=2.6.0
Requires (Dev)
- mikey179/vfsstream: ^1.5
- phpunit/phpunit: >=4.1.0
- satooshi/php-coveralls: <1.0
- symfony/browser-kit: >=2.7.0
- symfony/dom-crawler: >=2.7.0
- symfony/finder: >=2.7.0
- symfony/form: >=2.7.0
- symfony/framework-bundle: >=2.7.0
- symfony/monolog-bundle: >=2.7.0
- symfony/routing: >=2.7.0
This package is not auto-updated.
Last update: 2024-01-15 08:27:54 UTC
README
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.