惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
Intezer
Google DeepMind News
Google DeepMind News
有赞技术团队
有赞技术团队
博客园 - Franky
Jina AI
Jina AI
博客园_首页
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Engineering at Meta
Engineering at Meta
B
Blog
A
About on SuperTechFans
J
Java Code Geeks
WordPress大学
WordPress大学
GbyAI
GbyAI
N
News | PayPal Newsroom
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
T
The Exploit Database - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
Netflix TechBlog - Medium
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Palo Alto Networks Blog
U
Unit 42
Vercel News
Vercel News
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Know Your Adversary
Know Your Adversary
博客园 - 三生石上(FineUI控件)
AWS News Blog
AWS News Blog
Latest news
Latest news
V
V2EX
Y
Y Combinator Blog
Scott Helme
Scott Helme
博客园 - 叶小钗
美团技术团队
A
Arctic Wolf
S
Secure Thoughts
H
Help Net Security
L
LangChain Blog
博客园 - 司徒正美
V2EX - 技术
V2EX - 技术
P
Proofpoint News Feed
M
MIT News - Artificial intelligence
I
InfoQ
Cyberwarzone
Cyberwarzone
S
SegmentFault 最新的问题
Hacker News - Newest:
Hacker News - Newest: "LLM"

f2h2h1's blog

使用yii3实现一个微框架 claw养殖技术 计算机网络基础知识 定时任务 ACME的使用经验 magento2加上varnish缓存 开发Magento2的模块 socket编程 一些开发笔记 一段CSDN文章主要内容的油猴脚本 电子邮件的不完整总结 git的笔记 在Windows下配置PHP服务器 终端,控制台和外壳 PHP各种运行方式的不完整总结 把网页导出成PDF 和颜色相关的笔记 HTTP认证方式的不完整总结 SEO的经验 密码学入门简明指南 文件的上传和下载 用纯CSS3实现的滑动按钮 在VSCode里调试PHP Linux的GUI 关于字符编码的一些坑 nc的使用和原理 在Windows下安装Magento2 对JS原型链的理解 使用docker-compose部署magento2 浏览器和服务器通讯方式的不完整总结 观察网站性能 一些关于Linux的笔记 telnet的不完整总结 在Windows下安装pear MySQL的时间类型和时间相关的函数 Windows下通过PEB读取进程的环境变量 关于 在VSCode里使用Xdebug远程调试PHP 在Windows下搭建git服务 关于环境变量的不完整总结 使用shell实现的kv数据库 如何完成以xx管理系统为选题的毕业设计 数字号码资源 各种标记语言 使用PowerShell实现的http服务器 kind相关经验 DNSSEC简介 nginx+ffmpeg+websocket实现的直播例子 使用Tesseract识别字符验证码 使用docker部署nuxt FirstData后台的设置 paypal,firtdata,支付宝的不完整接入指南 微信支付的不完整接入指南 用docker-compose部署lnmp环境 mongodb分片 练习
在magento2中使用persisted-query
2025-09-29 · via f2h2h1's blog

什么是 persisted query

Github - scandipwa/persisted-query

Packagist - scandipwa/persisted-query

scandipwa/persisted-query 是一个用于提升 magento2 graphql 响应速度的库。 大致原理是,把请求的解释缓存在 redis ,把响应的结果缓存在 full page cache (通常是 varnish) 。 只用于 query ,不用于 mutation

persisted-query 依赖

  • Redis
  • Varnish
  • PHP ext-phpredis

安装

  1. 通过 composer 安装
composer require scandipwa/persisted-query:^2.2
  1. 修改配置文件 app/etc/env.php

    • cache中加上这一段
        'persisted-query' => [
            'redis' => [
                'host' => 'localhost',
                'scheme' => 'tcp',
                'port' => '6379',
                'database' => '5'
            ]
        ],
    
    • 在 cache_types 中加上这一段
    'persisted_query_response' => 1,
    
  2. 修改配置文件 app/etc/config.php

'ScandiPWA_PersistedQuery' => 1,
  1. 安装完后记得运行构建命令。大致例子,仅供参考
php bin/magento setup:upgrade && \
php bin/magento setup:di:compile && \
php bin/magento setup:static-content:deploy -f && \
php bin/magento indexer:reindex && \
php bin/magento cache:flush;

使用

大致的使用流程

  1. 先发送一次 PUT 请求
    • url 里需要带上一个 hash 参数, hash 的值是一个随机数,这个值不能重复
    https://localhost/graphql?hash=2443957263
    
    • PUT 请求成功后会返回 201
    HTTP/1.1 201 Created
    Content-Type: application/json
    Content-Length: 55
    
    {"error":false,"code":"1","message":"Query registered"}
    
  2. 后续发送 GET 请求, GET 请求中也需要带上 hash 参数
    • 后续的 GET 请求才会有具体的数据

关键代码的位置 vendor/scandipwa/persisted-query/src/Plugin/PersistedQuery.php

可以通过这个 http 头设置过期时间 SW-cache-age ,这是设置 查询的过期时间

如果没有特别的设置,缓存在刷新时才会失效

  • 刷新查询
    bin/magento scandipwa:pq:flush
    
  • 刷新响应
    bin/magento cache:flush persisted_query_response
    

缓存无效时会返回 401

HTTP/1.1 410 Gone
Content-Type: application/json
Content-Length: 61

{"error":true,"code":"410","message":"Query hash is unknown"}

不带参数的请求

  1. 先发送一次 PUT 请求
    curl 'https://localhost/graphql?hash=2443957263' \
      -X 'PUT' \
      -H 'accept: */*' \
      -H 'content-type: application/json' \
      --data-raw '{"query":"\nquery {\n appConfig {\n all_category_cms_page_id\n app_content\n {\n id\n value\n } } }"}'
    
  2. 后续发送 GET 请求
    curl -X 'GET' 'https://localhost/graphql?hash=2443957263'
    

带参数的请求

  1. 先发送一次 PUT 请求
    curl 'https://localhost/graphql?hash=2443957282' \
    -X 'PUT' \
    -H 'accept: */*' \
    -H 'content-type: application/json' \
    -H 'Cookie: XDEBUG_SESSION=vscode;' \
    -d '{
        "query": "query GetProductsBySkus($_filter:ProductAttributeFilterInput!, $_pageSize:Int) { products(search: \"*\", filter: $_filter, pageSize: $_pageSize ) { items { id uid sku name image { url } url_key url_suffix stock_status categories { uid name } } } }"
    }'
    
  2. 后续发送 GET 请求
    curl -X 'GET' 'https://localhost/graphql?hash=2443957282&_filter=%257B%2522sku%2522%253A%257B%2522in%2522%253A%255B%2522sku1%2522%252C%2522sku2%2522%252C%2522sku3%2522%255D%257D%257D&_pageSize=1'
    

如何构造一个带参数的请求

假设这是原本的请求

curl 'https://localhost/graphql' \
  -X 'POST' \
  -H 'accept: */*' \
  -H 'content-type: application/json' \
  -H 'Cookie: XDEBUG_SESSION=vscode;' \
  -d '{
    "query": "query GetProductsBySkus($_filter:ProductAttributeFilterInput!, $_pageSize:Int) { products(search: \"*\", filter: $_filter, pageSize: $_pageSize ) { items { id uid sku name image { url } url_key url_suffix stock_status categories { uid name } } } }",
    "variables":{"_filter":{"sku":{"in":["sku1","sku2","sku3"],"_pageSize":1}}}
}'
  1. 删除请求体中的 variables
  2. 把请求的方法改成 PUT
  3. url 中加上 hash 参数
  4. 这是最后的结果
curl 'https://localhost/graphql?hash=2443957282' \
  -X 'PUT' \
  -H 'accept: */*' \
  -H 'content-type: application/json' \
  -H 'Cookie: XDEBUG_SESSION=vscode;' \
  -d '{
    "query": "query GetProductsBySkus($_filter:ProductAttributeFilterInput!, $_pageSize:Int) { products(search: \"*\", filter: $_filter, pageSize: $_pageSize ) { items { id uid sku name image { url } url_key url_suffix stock_status categories { uid name } } } }",
}'

后续的请求中,把 variables 转换为 url编码,再直接加在 url 里

curl -X 'GET' 'https://localhost/graphql?hash=2443957282&_filter=%257B%2522sku%2522%253A%257B%2522in%2522%253A%255B%2522sku1%2522%252C%2522sku2%2522%252C%2522sku3%2522%255D%257D%257D&_pageSize=1'

这是把 variables 转换为 url编码 的伪代码

$variables = '{"_filter":{"sku":{"in":["sku1","sku2","sku3"]}},"_pageSize":1}';

$variables = json_decode($variables, true);

foreach ($variables as $key => $value) {
    $variables[$key] = urlencode(json_encode($value));
}

echo http_build_query($variables);