我创建了一个代理环境(使用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",
    ...
  }

使用yarn,但请根据需要将其替换为npm等。根据需要,您可以将自定义的库fork到您自己的环境中。

在项目的根目录下放置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 })
在本地调试时,需要执行上述设置。请通过环境变量等方式切换代码的启用或禁用。
localhost:8015端口将设置为proxy.js中设置的proxyPort的值。
注意,通过执行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可以方便快捷地进行开发。虽然需要添加一些用于模拟环境的代码,但我认为这是值得的,请务必尝试一下。

广告
将在 10 秒后关闭
bannerAds