base on Serve millions of requests by caching with Cloudflare <picture>
<source media="(prefers-color-scheme: dark)" srcset="https://banners.beyondco.de/Laravel%20Cloudflare%20Cache.png?theme=dark&packageManager=composer+require&packageName=yediyuz%2Flaravel-cloudflare-cache&pattern=architect&style=style_1&description=Serve+millions+of+requests+by+caching+with+Cloudflare&md=1&showWatermark=0&fontSize=100px&images=server">
<source media="(prefers-color-scheme: light)" srcset="https://banners.beyondco.de/Laravel%20Cloudflare%20Cache.png?theme=light&packageManager=composer+require&packageName=yediyuz%2Flaravel-cloudflare-cache&pattern=architect&style=style_1&description=Serve+millions+of+requests+by+caching+with+Cloudflare&md=1&showWatermark=0&fontSize=100px&images=server">
<img alt="Package Image" src="https://banners.beyondco.de/Laravel%20Cloudflare%20Cache.png?theme=light&packageManager=composer+require&packageName=yediyuz%2Flaravel-cloudflare-cache&pattern=architect&style=style_1&description=Serve+millions+of+requests+by+caching+with+Cloudflare&md=1&showWatermark=0&fontSize=100px&images=server">
</picture>
# Laravel Cloudflare Cache
<p>
<a href="https://github.com/yediyuz/laravel-cloudflare-cache/actions"><img src="https://img.shields.io/github/actions/workflow/status/yediyuz/laravel-cloudflare-cache/tests.yml?branch=master&label=tests" alt="Test Status"></a>
<a href="https://packagist.org/packages/yediyuz/laravel-cloudflare-cache"><img src="https://img.shields.io/packagist/v/yediyuz/laravel-cloudflare-cache.svg?style=flat-square" alt="Latest Release"></a>
<a href="https://github.com/mertasan/tailwindcss-variables/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg?label=license" alt="License"></a>
</p>
You can serve millions of requests with this package. This package provides cacheable routes for Cloudflare. Thanks to Cloudflare, your static pages are served efficiently, reducing the load on your servers if they are cached for the TTL (Time to Live) duration. You can purge the cache whenever you need with this package.
## Installation
You can install the package via composer:
```bash
composer require yediyuz/laravel-cloudflare-cache
```
You can publish the config file with:
```bash
php artisan vendor:publish --tag="cloudflare-cache-config"
```
Add environment variables to .env file
```dotenv
[email protected] #Cloudflare account email address
CLOUDFLARE_CACHE_KEY=XXXXXXX #Cloudflare API_KEY
CLOUDFLARE_CACHE_IDENTIFIER=XXXXXXX #ZONE_ID
CLOUDFLARE_DEFAULT_CACHE_TTL=600 #10 minutes
CLOUDFLARE_CACHE_DEBUG=false
```
### Add `Rule` on Cloudflare
To active caching on static pages, you need to add `page rule` **OR** `cache rule` on Cloudflare.
For page rule:
- If the URL matches: `www.example.com/*`
- Setting: Cache Level
- Value: Cache Everything
For the cache rule:
- Field: hostname
- Operator: equals
- Value: `example.com`
- Then: Eligible for cache
https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/
## Usage
### Define routes to cache
You can use cache groups for your static contents.
```php
Route::cache()->group(function () {
Route::get('/content', function () {
return 'content';
});
});
```
You can use cache tags, so you can clear your caches easily. Specify custom ttl for expire time in seconds. When you do not pass ttl, it will use default ttl given in the config.
```php
Route::cache(tags: ['tag1', 'tag2'], ttl: 600)->group(function () {
Route::get('/content_with_tags', function () {
return 'content';
});
});
Route::cache(tags: ['staticPages'])->group(function () {
//
});
```
> [!WARNING]
> Be careful caching your routes! Do not cache your dynamic pages such as admin panel or form based pages!
### Clear Cache
#### Purges everything
https://developers.cloudflare.com/cache/how-to/purge-cache/purge-everything/
```php
CloudflareCache::purgeEverything()
```
#### Purges by urls
https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/
```php
CloudflareCache::purgeByUrls([
'https://example.com/hello',
])
```
#### Purges by prefixes (Enterprise only)
https://developers.cloudflare.com/cache/how-to/purge-cache/purge_by_prefix/
```php
CloudflareCache::purgeByPrefixes([
'www.example.com/foo',
])
```
#### Purges by tags (Enterprise only)
https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/
```php
CloudflareCache::purgeByTags([
'staticPages',
])
```
#### Purges by hostname (Enterprise only)
https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-hostname/
```php
CloudflareCache::purgeByHosts([
'www.example.com',
'images.example.com',
])
```
Post update example to clear cache
```php
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UpdatePostRequest;
use App\Models\Post;
use Yediyuz\CloudflareCache\Facades\CloudflareCache;
class PostController extends Controller
{
public function update(Post $post, UpdatePostRequest $request)
{
$post->update($request->validated());
CloudflareCache::purgeByUrls([
route('post.show', $post->id)
]);
return back()->with('message', 'Post updated and url cache purged');
}
}
```
## Testing
```bash
composer test
```
## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
## Contributing
Please see [CONTRIBUTING](https://github.com/yediyuz/.github/blob/master/CONTRIBUTING.md) for details.
## Security
If you've found a bug regarding security please mail
[email protected] instead of using the issue tracker.
## Credits
- [Emre Dipi](https://github.com/emredipi)
- [Mert Aşan](https://github.com/mertasan)
- [All Contributors](../../contributors)
## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
", Assign "at most 3 tags" to the expected json: {"id":"8856","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"