Cannot call REST api from web worker using aws-ampliy
Before opening, please confirm:
- [X] I have searched for duplicate or closed issues and discussions.
- [X] I have read the guide for submitting bug reports.
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
JavaScript Framework
React
Amplify APIs
REST API
Amplify Version
v6
Amplify Categories
api
Backend
Amplify CLI
Environment information
# Put output below this line
System:
OS: Windows 11 10.0.22621
CPU: (6) x64 Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
Memory: 3.06 GB / 15.94 GB
Binaries:
Node: 18.18.0 - C:\Program Files\nodejs\node.EXE
npm: 10.1.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 120.0.6099.217
Edge: Chromium (120.0.2210.133)
Internet Explorer: 11.0.22621.1
npmPackages:
@aws-amplify/ui-react: ^6.1.1 => 6.1.1
@aws-amplify/ui-react-internal: undefined ()
@aws-amplify/ui-react-storage: ^3.0.10 => 3.0.10
@types/react: ^18.2.43 => 18.2.47
@types/react-dom: ^18.2.17 => 18.2.18
@vitejs/plugin-react: ^4.2.1 => 4.2.1
aws-amplify: ^6.0.12 => 6.0.12
aws-amplify/adapter-core: undefined ()
aws-amplify/analytics: undefined ()
aws-amplify/analytics/kinesis: undefined ()
aws-amplify/analytics/kinesis-firehose: undefined ()
aws-amplify/analytics/personalize: undefined ()
aws-amplify/analytics/pinpoint: undefined ()
aws-amplify/api: undefined ()
aws-amplify/api/server: undefined ()
aws-amplify/auth: undefined ()
aws-amplify/auth/cognito: undefined ()
aws-amplify/auth/cognito/server: undefined ()
aws-amplify/auth/enable-oauth-listener: undefined ()
aws-amplify/auth/server: undefined ()
aws-amplify/datastore: undefined ()
aws-amplify/in-app-messaging: undefined ()
aws-amplify/in-app-messaging/pinpoint: undefined ()
aws-amplify/push-notifications: undefined ()
aws-amplify/push-notifications/pinpoint: undefined ()
aws-amplify/storage: undefined ()
aws-amplify/storage/s3: undefined ()
aws-amplify/storage/s3/server: undefined ()
aws-amplify/storage/server: undefined ()
aws-amplify/utils: undefined ()
eslint: ^8.55.0 => 8.56.0
eslint-plugin-react: ^7.33.2 => 7.33.2
eslint-plugin-react-hooks: ^4.6.0 => 4.6.0
eslint-plugin-react-refresh: ^0.4.5 => 0.4.5
react: ^18.2.0 => 18.2.0
react-dom: ^18.2.0 => 18.2.0
vite: ^5.0.8 => 5.0.11
npmGlobalPackages:
@forge/cli: 4.1.1
atlas-connect: 0.8.1
firebase-tools: 10.7.0
mongodb-realm-cli: 2.4.2
npm-check-updates: 12.5.9
npm: 10.1.0
serve: 14.2.1
Describe the bug
From a web worker (on Chrome), invoking a get request to Amplify REST API fails with the following error.
GET call failed: InvalidApiName: API name is invalid.
The same request running in the main thread is successful.
Expected behavior
Works the same as when invoked in the main thread.
Reproduction steps
Please see code in snippet below.
Code Snippet
// Put your code below this line.
// WEB WORKER CODE (FAILS)
/* eslint-disable no-restricted-globals */
import { get } from "aws-amplify/api";
console.log("Worker started");
async function getFcn() {
try {
const restOperation = get({
apiName: 'sandbox1',
path: '/sandbox1'
});
const response = await restOperation.response;
console.log('GET call succeeded: ', response);
} catch (error) {
console.log('GET call failed: ', error);
}
}
getFcn();
// MAIN THREAD CODE (WORKS - see get request within useEffect)
import '@aws-amplify/ui-react/styles.css';
import { get } from 'aws-amplify/api';
import { useEffect, useMemo } from 'react';
const Page = () => {
const myWorker = useMemo(() => {
return new Worker(new URL("./worker1.js", import.meta.url), {
type: "module"
})
}, [])
myWorker.postMessage('Hi worker')
myWorker.onmessage = function (e) {
console.log('Message received from worker', e);
}
useEffect(() => {
async function getFcn() {
try {
const restOperation = get({
apiName: 'sandbox1',
path: '/sandbox1'
});
const response = await restOperation.response;
console.log('GET call succeeded: ', response);
} catch (error) {
console.log('GET call failed: ', error);
}
}
getFcn();
}, []);
return (
<div>
Hello again
</div>
)
};
export default Page;
Log output
</details>
### aws-exports.js
amplifyconfiguration.json:
{ "aws_project_region": "us-east-1", "aws_cognito_identity_pool_id": "us-east-1:0598a33f-9357-4ba8-9cb2-876da7c9bb85", "aws_cognito_region": "us-east-1", "aws_user_pools_id": "us-east-1_JAAkzlaKS", "aws_user_pools_web_client_id": "27s2qe07qgpp0mf7083dian9ua", "oauth": { "domain": "sandboxauth167bef521-67bef521-dev.auth.us-east-1.amazoncognito.com", "scope": [ "phone", "email", "openid", "profile", "aws.cognito.signin.user.admin" ], "redirectSignIn": "http://localhost:3000/", "redirectSignOut": "http://localhost:3000/", "responseType": "code" }, "federationTarget": "COGNITO_USER_POOLS", "aws_cognito_username_attributes": [ "EMAIL" ], "aws_cognito_social_providers": [ "GOOGLE" ], "aws_cognito_signup_attributes": [ "EMAIL" ], "aws_cognito_mfa_configuration": "OFF", "aws_cognito_mfa_types": [ "SMS" ], "aws_cognito_password_protection_settings": { "passwordPolicyMinLength": 8, "passwordPolicyCharacters": [] }, "aws_cognito_verification_mechanisms": [ "EMAIL" ], "aws_cloud_logic_custom": [ { "name": "sandbox1", "endpoint": "https://n66fgb5l98.execute-api.us-east-1.amazonaws.com/dev", "region": "us-east-1" } ] }
### Manual configuration
_No response_
### Additional configuration
_No response_
### Mobile Device
_No response_
### Mobile Operating System
_No response_
### Mobile Browser
_No response_
### Mobile Browser Version
_No response_
### Additional information and screenshots
_No response_
Thanks for creating this issue from the Discord Office Hours session today, @alex-breen. Can you clarify how you're initializing Amplify within the web worker or if it's being imported? And based on the error that you're seeing, can you double check that the API names in the web worker exactly match what's in your config (i.e. casing/spelling)?
- I am importing 'aws-amplify/api'. Like this;
import { get } from "aws-amplify/api"; - The API names are the same. I copied the same code from the main thread component, where the call works.
Side note - I (clumsily) tried a few different things with the web worker to try to make it work. I imported a window polyfill - no change. I called Amplify.configure(amplifyconfig) inside the webworker - I no longer got the invalidAPIName error, but instead got errors about not having authentication credentials. I added authCode into the options field - but I still got errors about missing creds.
Ok, thanks for the quick response and glad to hear we’re past the original error then at least! It sounds like what’s happening here is you’ve got some type of network requests needing authenticated credentials happening in the web worker. Can you maybe share some additional context here about what you’re trying to do with the web worker?
If you’re trying to offload some of the work to the web worker, you may want to make any networks requests within the main thread but then hand off the response and other work to the web worker after it’s been received for additional processing. If you’re trying to do all this work in the web worker, that error seems like it’ll require you passing credentials into the other thread and require you writing your own credential and token providers (which we wouldn’t recommend).
Thanks @cwomack, that's helpful.
Here is the context about why I'm using a web worker:
- I use a web worker to run a machine learning transformer that would block the main thread if it weren't separated.
- After the transformer is done, the worker makes a
postto a Lamda function (using the API path set up using Amplify CLI). - When the Lambda is done, it returns a result to the web worker. After some processing, the web worker passes a result back to the main thread.
So, as an alternate method, if I can't invoke the get call from the web worker, I can pass the result back to the main thread and make the post to the API/Lambda from there (like you suggested, just in reverse). The reason I wanted to avoid doing that is so I didn't have to pass large payloads of data between the worker and the main thread. And just to keep the logic in one place.
@alex-breen, we're going to mark this as a feature request at this point to track better support out of the box for web workers. Appreciate you giving the additional context and use cases here.