apollo
apollo copied to clipboard
Use Apollo Nuxt Module with AWS Amplify (appsync) API
What problem does this feature solve?
I tried to stick with this module when working with a GraphQL AWS API. I couldn't configure how to attach to the request headers the requested API key.
When "edit and resend" the request to add ''x-api-key" as key with the related key as value, it works. See https://stackoverflow.com/q/60816883/3793161
What does the proposed changes look like?
If it is already possible, it's a feature request for the readme. If not, it does not look like a big leap to allow the addition of custom headers for cases like this.
I'll show some support for this too. I'm trying to get Apollo to talk to my Rails GraphQL backend, but I'm using Devise Token Auth which requires setting specific headers for authentication:
client- unique string to identify this clientaccess-token- the token, expires every 2 weeks
It looks like the Apollo module is setup for Basic/Bearer authentication, so I presume it can't be too tricky to allow us to set custom headers.
I figured out a solution to my problem of dynamically setting headers.
In nuxt.config.js you can use clientConfigs to provide your own file, rather than a static options object. That file can export a function that accepts a context argument, where you can retrieve the token and append it to the headers for the apollo request.
// nuxt.config.js
export default {
apollo: {
clientConfigs: {
default: '~/apollo/default-client.js'
}
},
}
// apollo/default-client.js
export default function(context) {
const token = context.app.$cookies.get("apollo-token");
return {
httpEndpoint: `http://api.com/graphql`,
httpLinkOptions: {
headers: {
"access-token": token.accessToken,
client: token.client,
uid: token.uid,
expiry: token.expiry
}
}
}
}
Edit: this doesn't seem to work client-side without fully reloading the page 😢
@Billybobbonnet Here's an example from one of my codebases of how to achieve normal connection (for mutations and queries):
// nuxt.config.js
export default {
apollo: {
clientConfigs: {
default: {
httpEndpoint: `https://${process.env.VUE_APP_WS_GATEWAY_ENDPOINT || 'localhost:4030'}/graphql`,
httpLinkOptions: {
headers: {
'x-api-key': process.env.VUE_APP_WS_API_KEY || 'YOUR_API_KEY',
},
},
},
}
},
}
there is a caveat unfortunately, I just couldn't make the subscriptions work, I tried a few strategies in order to have the headers set on the websocket link, but none seem to do it. I think the fault lies with the vue-apollo package.
Here is what I tried:
- Ideally this would be awesome to have working:
// nuxt.config.js
export default {
apollo: {
clientConfigs: {
default: {
httpEndpoint: `https://${process.env.VUE_APP_WS_GATEWAY_ENDPOINT || ''}`,
wsEndpoint: `wss://${process.env.VUE_APP_WS_GATEWAY_ENDPOINT || ''}`,
websocketsOnly: true,
httpLinkOptions: {
headers: {
'x-api-key': process.env.VUE_APP_WS_API_KEY || '',
},
},
wsLinkOptions: {
headers: {
'x-api-key': process.env.VUE_APP_WS_API_KEY || '',
},
},
}
}
},
}
Even more so by dropping the whole http part.
- I've tried to set a link instead of the settings above
// nuxt.config.js
export default {
apollo: {
clientConfigs: {
default: {
link: '~/apollo/websocket',
wsEndpoint: `wss://${process.env.VUE_APP_WS_GATEWAY_ENDPOINT || ''}`,
websocketsOnly: true,
}
}
}
}
// apollo/websocket.ts file got the content from https://vue-apollo.netlify.app/guide/apollo/subscriptions.html#setup .
- As per the hasura blog https://hasura.io/learn/graphql/vue/subscriptions/1-subscription/
// nuxt.config.js
export default {
apollo: {
clientConfigs: {
default: {
link: '~/apollo/websocket',
wsEndpoint: `wss://${process.env.VUE_APP_WS_GATEWAY_ENDPOINT || ''}`,
websocketsOnly: true,
}
}
}
}
// apollo/websocket.ts file
const link = new WebSocketLink({
uri:`wss://${process.env.VUE_APP_WS_GATEWAY_ENDPOINT || ''}`,
options: {
reconnect: true,
timeout: 30000,
connectionParams: () => {
return { headers: {
'x-api-key': process.env.VUE_APP_WS_API_KEY || '',
} };
},
}
});
Hi Team, I am also interested in being able to setup the module with AppSync and more specifically with the COGNITO_USER_POOLS auth type. Currently @decebal workaround works great for the API_KEY auth type but I am unable to find a way to send the JWT tokens as part of the Authorization header. Cheers
@Stf-F did u find a solution?
@Stf-F @podlebar I know this has been a while since your original comment but have you found a way to make it work with Cognito user pools?
What I'm not sure about is how to dynamically set the Authorization header for my AppSync requests.
@imduchy , for COGNITO_USER_POOLS, the authorization header is a bit tricky (as said on here, where it worked after they removed Bearer from the header content). For me, it started working with this configuration for queries and mutations (on version v5):
nuxt.config.js:
apollo: {
clients: {
default: {
httpEndpoint: 'https://<your_API_ID>.appsync-api.<your-aws-region>.amazonaws.com/graphql',
wsEndpoint: 'wss://<your_API_ID>.appsync-realtime-api.<your-aws-region>.amazonaws.com/graphql',
tokenName: 'apollo-token',
tokenStorage: 'localStorage',
websocketsOnly: false,
authType: 'Bearer'
},
},
},
On my store/userStore.ts (using pinia) I set the token for Apollo:
async login(username) {
// ...
const { onLogin } = useApollo();
onLogin(this.token);
}
async logout() {
// ....
const { onLogout } = useApollo();
onLogout();
}
And after that, you just do normal queries in your pages using useAsyncQuery(). If that doesn't work for you, you can try setting authType: null and that way the header won't contain Bearer . Also, testing with the app Postman was quite useful.
Note: I'm still working on subscriptions, so this configuration probably won't work for that. Also, to obtain the token I'm using the package 'amazon-cognito-identity-js'