我创建了一个代理环境(使用NextJS)来实现在 AWS Amplify mock API 中舒适地使用 subscription
事件的过程
-
- Amplify mock api は、ローカル開発を加速させることができるので非常に便利
-
- しかし、現状(2022年3月)時点では、チュートリアルに書かれた方法では動作しない
- AppSyncを使いたい大きな動機が、subscriptionであり、どうしてもローカルでシミュレートしたい
解答: 处理方案
-
- 結局のところ、mock apiのサーバ自体はsubscriptionに対応している
-
- しかし、aws-sdkが未対応のため、誤ったエンドポイントに通信しており使用できない状況
- ローカルにプロキシを立てることで、sdkからmock apiへの通信を修正すれば使用できる
行动验证版
“aws-amplify”: “^4.3.14” 可以被重述为 “aws-amplify”版本号为”^4.3.14″。
“next”: “^11.1.3” 可以被重述为 “next”的版本号为”^11.1.3″。
详细内容
mock api不支持订阅功能吗?
据说最初订阅功能存在一个错误,但已经修复了。
https://github.com/aws-amplify/amplify-cli/issues/6026
在托管虚拟的 API 中运行时,我们发现客户端通信的目标似乎有问题。这可能是由于 AWS-SDK 的修复过程出现了偏差所导致的。
根据这个问题,在订阅的模拟API操作时,访问的地址被错误地定向到了/graphql/realtime而不是/graphql,因此需要进行重定向等更改。可以参考此链接:https://github.com/aws-amplify/amplify-cli/issues/9621
只需要修改URL.
只需将对/graphql/realtime的访问修改为对/graphql(/对/graphql的访问保持不变),问题似乎就可以解决。
如果你正在使用NextJS,我尝试了仅需要进行rewrites设置,但它没有正常工作。我还发现了一篇文章,建议不要随意使用rewrite。
我觉得,为了创建测试环境,我不想加入修改设置,所以决定考虑其他方法。
使用Node模块搭建代理服务器。
考虑过单独设置nginx等代理应用,但考虑到在NextJS项目中可以通过(node_modules)进行管理会更方便,因此决定进行以下自定义配置来设置代理。
代理服务器的策略
node-http-proxyをベースにする
URL書き換えのオプションがなかったのでカスタマイズする
package.jsonにコマンド記載してyarn等で起動管理する
自定义node-http-proxy
自定義結果請參考blueoath-video-ec/node-http-proxy。
创建一个新的pathRewrite选项,通过正则表达式对URL进行重写。
if (options.pathRewrites && (options.pathRewrites instanceof Array)) {
for (var i = 0; i < options.pathRewrites.length; i++) {
console.log(outgoing.path);
var from = options.pathRewrites[i].from
var to = options.pathRewrites[i].to
outgoing.path = outgoing.path.replace(new RegExp(from, 'g'), to);
}
}
使用方法大致如下。
var proxy = new httpProxy.createProxyServer({
...
pathRewrite: [
{ from: "^/graphql/realtime", to: "/graphql" }
],
...
});
将其包含在package.json文件中
首先,添加定制化的库。
在package.json中添加以下内容,然后运行yarn install命令。
"devDependencies": {
...
"node-http-proxy": "git+https://github.com/blueoath-video-ec/node-http-proxy.git",
"kill-port": "^1.6.1",
...
}
在项目的根目录下放置proxy.json文件,并填写代理服务器的启动代码。
proxy.js
// 注意:我们使用了自定义的代理(添加了 pathRewrite)
// https://github.com/http-party/node-http-proxy
// https://github.com/blueoath-video-ec/node-http-proxy
var http = require(‘http’);
var httpProxy = require(‘node-http-proxy’);
var mockAPIServerPort = 20002;
var proxyPort = 8015;
//
// 设置我们的服务器以代理标准的HTTP请求
//
var proxy = new httpProxy.createProxyServer({
target: {
protocol: ‘http’,
host: ‘localhost’,
port: mockAPIServerPort,
path: ‘/’,
},
pathRewrite: [
{ from: “^/graphql/realtime”, to: “/graphql” }
],
changeOrigin: true
});
var proxyServer = http.createServer(function (req, res) {
proxy.web(req, res, function (err) {
// 现在你可以获取错误信息
// 并自行处理
// if (err) throw err;
console.log(“http错误 === “)
console.log(err);
});
});
//
// 监听 ‘upgrade’ 事件并代理 WebSocket 请求
//
proxyServer.on(‘upgrade’, function (req, socket, head) {
proxy.ws(req, socket, head, function (err) {
// 现在你可以获取错误信息
// 并自行处理
// if (err) throw err;
console.log(“ws错误 === “)
console.log(err);
socket.close();
})
});
console.log(“mockAPIServerPort: ” + mockAPIServerPort)
console.log(“proxyPort: ” + proxyPort)
proxyServer.listen(proxyPort);
mockAPIServerPort 为模拟 API 服务器的端口。
proxyPort 为我们创建的代理服务器的端口。
增加代理服务器启动选项
在 package.json 文件中添加以下内容。
"scripts": {
...
"mock:api": "yarn kill-amplify-mock-api && amplify mock api",
"mock:proxy": "node ./proxy.js",
"kill-amplify-mock-api": "kill-port 20002 && kill-port 20003"
},
在中文中進行本地化重述:
當輸入「yarn mock:api」時,將停止模擬伺服器並啟動代理伺服器。
我会使用这个应用程序!
搭建代理服务器并不足以使用模拟API。需要修改Amplify.configure的aws-exports信息,以便将端点指向代理服务器。有关配置设置,请参考此处。
import awsExports from '../aws-exports'
//Amplify.configure({ ...awsExports, ssr: true })
let usingProxy = awsExports
usingProxy.aws_appsync_graphqlEndpoint = 'http://localhost:8015/graphql'
Amplify.configure({ ...usingProxy, ssr: true })
注意,通过执行amplify mock api,aws-exports.js的值将自动更改(mock api的好处)。aws-exports.js
const awsmobile = {
…
“aws_appsync_graphqlEndpoint”: “http://192.168.12.8:20002/graphql”,
上述的:20002是mock api服务器的端点。
将其更改为:
somewhere-in-the-app.tsx
usingProxy.aws_appsync_graphqlEndpoint = ‘http://localhost:8015/graphql’
以覆盖为代理服务器的端点。
总结
AWS Amplify模拟API的订阅功能可以正常运行,但需要进行一些改进。
由于Amplify(AppSync)具有订阅功能,因此在本地环境中运行模拟API可以方便快捷地进行开发。虽然需要添加一些用于模拟环境的代码,但我认为这是值得的,请务必尝试一下。