Use Postman to test a service with GraphQL in AWS (AppSync, Apollo) - react-apollo

I'm trying to call a service through Graphql with Postman. From my app (React) I can use all the services with no problem (so, they are running ok), but I want to test them alone with Postman.
I'm using AppSync, this is my configuration:
const AppSyncConfig = {
url: environments.configAws.graphql.aws_appsync_graphqlEndpoint,
region: environments.configAws.graphql.aws_appsync_region,
auth: {
type: AUTH_TYPE.API_KEY,
apiKey: environments.configAws.graphql.aws_appsync_apiKey,
}
};
The environments vars are this:
graphql: {
aws_project_region: "us-east-1",
aws_appsync_graphqlEndpoint: "https://XXXXXXXXXXXXX.appsync-api.us-east-1.amazonaws.com/graphql",
aws_appsync_region: "us-east-1",
aws_appsync_authenticationType: "API_KEY",
aws_appsync_apiKey: "da2-XXXXXXXXXXXX"
}
And the app use this to make a query:
const client = new AWSAppSyncClient(AppSyncConfig, {
link: createAppSyncLink({ ...AppSyncConfig,
resultsFetcherLink: ApolloLink.from([
setContext((request, previousContext) => ({
headers: { ...previousContext.headers,
Authorization: localStorage.getItem('token') ? localStorage.getItem('token') : ''
}
})),
createHttpLink({
uri: AppSyncConfig.url
})
])
})
});
const data_configs = client.readQuery({ query: query_configs });
In Postman I have this config, but I'm getting an error:
I took this code today, I haven't work before with Graphql (so neither with AppSync, ApolloLink, etc), but I ask in case it has a simple solution, or at least a hint for what should I check. Thanks.

I believe the header name for the API KEY is not API_KEY but x-api-key.

I was able to invoke my AWS Amplify GraphQL endpoint with Postman using the following steps:
Create a new Postman request
Set the type of request to 'POST'
Enter the API URL in the request URL
Add a header of 'x-api-key': {{API KEY}} in the Headers tab
Add a body of consisting of a well formed GraphQL query
Click Send

Put "x-api-id" in the request header works for me.

Here is the images which I have implemented in Postman.
First image has header and other details, and in Second image check Raw Body Section.

It's the screenshot for 'x-api-key' from the Authentication tab in Postman. Its type is API Key and it can be also used like this.

Related

GraphQL with ApolloServer says "GET query missing." even though I have playground set to true the way another post advised

I am trying to use Postman to hit a graphQL endpoint to teach myself how it works. I have a database with user data prepopulated and two Postman routes that should work but don't work.
The requests I am trying to send via Postman:
(1) Using GraphQL mode under the Body tab
{
User {
first_name
last_name
}
}
(2) using the raw mode under the Body tab
{
user {
first_name
last_name
}
}
In both cases I have correctly set the headers Content-Type to application/graphql. So it's not that.
I found two posts about this while Googling. Both are on StackOverflow.
(1) apollo-server returning GET query missing when playground is disabled
This one says basically, "do this":
const server = new ApolloServer({
introspection: true, // i inserted this line & the next one as specified
playground: true,
typeDefs,
resolvers,
})
(2) GET query missing: Implementing GraphQL Using Apollo On an Express Server
This one references the prior link. It's also for graph-server-express, and I'm using apollo-server-fastify
I also found Apollo Graphql with Fastify who also has "GET query missing." issue but no solution. It says to downgrade to fastify v2 but that's an old answer from 2020. This is 2022, we can do better.
Again the issue is that Postman says "GET query missing." to all my requests.
My server:
async function startApolloServer(typeDefs, resolvers) {
const apolloServer = new ApolloServer({
// introspection: true,
// playground: true, // to resolve "GET query missing." in Postman
typeDefs,
resolvers,
plugins: [
fastifyAppClosePlugin(fastify),
ApolloServerPluginDrainHttpServer({ httpServer: fastify.server }),
ApolloServerPluginLandingPageGraphQLPlayground(),
],
context: ({ request, reply }) => {
//Invaluable for debugging
if (env === "development") {
console.log("GOT A REQUEST: ", request.body);
}
return { knex, reply };
},
});
await apolloServer.start();
fastify
.register(helmet)
.register(require("fastify-sensible"))
.register(require("fastify-healthcheck"))
.register(require("fastify-formbody"))
.register(apolloServer.createHandler());
await fastify.listen(serviceListeningPort);
console.log(
`🚀 Server ready at http://localhost:${serviceListeningPort}${apolloServer.graphqlPath}`
);
}
startApolloServer(typeDefs, resolvers);
Also, the updated version of Apollo Server seems to replace playground: true with ApolloServerPluginLandingPageGraphQLPlayground(), which for me enables a page that says "Loading GraphQL Playground" at the server root but never finishes loading.

How to access API Service for types and mutations from within lambda functions

We are currently working on an application using AWS Amplify. We have 10/15 Lambda functions defined through our Amplify project along with using several other plugins. The project itself is an Angular Application.
Right now, we are working on interfacing some 3rd party services into our Amplify project that utilizes publishing mutations for real time updates using #aws_subscribe. We can trigger these just fine based on the solution using a HTTP request; however, we are wondering if it is possible to reuse the mutation operations already generated within the API.service.ts file to provide consistent typing for both "clients". This will help maintain type control across both "clients" and catch errors earlier. It also prevents us from re-writing mutations/queries down the road.
Our current solution is working but seems inefficient.
Query Statement
const PublishReportingLocationWorkflowProgressUpdateMutation = `mutation PublishReportingLocationWorkflowProgressUpdate( $id: ID!, $status: WorkflowProgressUpdateStatus!, $reportingLocation_id: String! ) { publishReportingLocationWorkflowProgressUpdate(result: {id: $id, status: $status, reportingLocation_id: $reportingLocation_id}) { id status reportingLocation_id } }`;
HTTP Request Body
{
query: PublishReportingLocationWorkflowProgressUpdateMutation,
operationName: 'PublishReportingLocationWorkflowProgressUpdate',
variables: {
id: event.Payload.executionID,
status: 'COMPLETE',
reportingLocation_id: event.Payload.reportingLocation.id }
HTTP Call
let response = await axios({
method: 'POST',
url: process.env.API_URL,
data: mutation,
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.API_KEY,
}
});

nuxtjs middleware rest API raw data requests

I have build nuxtjs example with built in rest API requests with middleware technique. In index.js of my middleware section I put some code :
export default {
handler(req, res) {
res.write('Everything ok!')
console.log(req);
console.log(res);
res.end()
},
path: '/test15'
}
When I call http://ip:port/test15/?cmd=somecmd&param=testparam
In console.log I get params data in log, everything nice. No matter which method used, post or get, it also fixed in log.
The problem is when I try to send raw data (ex json) in request body or form data. I can`t see them in any log output.
So question is, is it possible to send some data in such requests via middleware ?
Thanks!
middleware in nuxt is a sandwich for internal routes aka client side. For your question serverMiddleware is the answer that work on the server side. You can checkout more here
Quick example:
In your nuxt.config.js file add like below
serverMiddleware: [
{ path: '/api/subscribe', handler: '~/api/subscribe' }
],
Then create an api folder you can create subscribe.js file to add relative api route.
import express from 'express'
const app = express()
app.get('/subscribe', async (req, res) => {
res.send('love to the world');
})
export default {
path: '/api',
handler: app
}

Nuxt Apollo with dynamic headers for a session based authentication

Apollo is not storing the header from the query dynamically.
pages/index.vue
methods: {
fetchCars() {
const token = Cookies.get('XSRF-TOKEN')
console.log(token) // 🟢 Token is shown in console
this.$apollo.query({
query: gql`
query {
cars {
uuid
name
}
}
`,
headers: {
'X-XSRF-TOKEN': token, // â­• Fetch without header
},
})
},
},
Is there a way to set the header value new for every Apollo request?
I have a separate Frontend and Backend. For the Frontend I am using Nuxt.js with Apollo. I want to have a session based communication with my server. For this reason I need to send the CSRF-Token with every Request.
Now the problem: On the first load of the page there is no Cookie set on the browser. I do a GET-Request on every initialization of my Nuxt application.
plugins/csrf.js
fetch('http://127.0.0.1:8000/api/csrf-cookie', {
credentials: 'include',
})
Now I have a valid Cookie set on my side and want to communicate with the GraphQL Server but my header is not set dynamically in the query. Does anyone know how I can solve this?
My Laravel Backend is throwing now a 419 Token Mismatch Exception because I did not send a CSRF-Token with my request.
Link to the repository: https://github.com/SuddenlyRust/session-based-auth
[SOLVED] Working solution: https://github.com/SuddenlyRust/session-based-auth/commit/de8fb9c18b00e58655f154f8d0c95a677d9b685b Thanks to the help of kofh in the Nuxt Apollo discord channel 🎉
In order to accomplish this, we need to access the code that gets run every time a fetch happens. This code lives inside your Apollo client's HttpLink. While the #nuxtjs/apollo module gives us many options, we can't quite configure this at such a high level.
Step 1: Creating a client plugin
As noted in the setup section of the Apollo module's docs, we can supply a path to a plugin that will define a clientConfig:
// nuxt.config.js
{
apollo: {
clientConfigs: {
default: '~/plugins/apollo-client.js'
}
}
}
This plugin should export a function which receives the nuxt context. It should return the configuration to be passed to the vue-cli-plugin-apollo's createApolloClient utility. You don't need to worry about that file, but it is how #nuxtjs/apollo creates the client internally.
Step 2: Creating the custom httpLink
In createApolloClient's options, we see we can disable defaultHttpLink and instead supply our own link. link needs to be the output of Apollo's official createHttpLink utility, docs for which can be found here. The option we're most interested in is the fetch option which as the docs state, is
a fetch compatible API for making a request
This boils down to meaning a function that takes uri and options parameters and returns a Promise that represents the network interaction.
Step 3: Creating the custom fetch method
As stated above, we need a function that takes uri and options and returns a promise. This function will be a simple passthrough to the standard fetch method (you may need to add isomorphic-fetch to your dependencies and import it here depending on your setup).
We'll extract your cookie the same as you did in your question, and then set it as a header. The fetch function should look like this:
(uri, options) => {
const token = Cookies.get('XSRF-TOKEN')
options.headers['X-XSRF-TOKEN'] = token
return fetch(uri, options)
}
Putting it all together
Ultimately, your ~/plugins/apollo-client.js file should look something like this:
import { createHttpLink } from 'apollo-link-http'
import fetch from 'isomorphic-fetch'
export default function(context) {
return {
defaultHttpLink: false,
link: createHttpLink({
uri: '/graphql',
credentials: 'include',
fetch: (uri, options) => {
const token = Cookies.get('XSRF-TOKEN')
options.headers['X-XSRF-TOKEN'] = token
return fetch(uri, options)
}
})
}
}

Unsupported content type with GraphIql apollo engine

I'm running apollo-server-express, and all works fine. I have 2 endpoints - 1 for graphiql (/graphql) and one for non-interactive (/client) queries (I know - they were called that before I started with apollo).
app.use('/client', bodyParser.json() ,
(req, res,next) => {
const context = { pool , apiKey:req.query.key , bidules };
if (server.isAuthorized(context.apiKey)) {
return graphqlExpress({
schema: schema,
context: context,
tracing: true,
cacheControl: {
defaultMaxAge: 30,
}
}) (req,res,next);
}
else {
res.setHeader('Content-Type', 'application/json');
res.status(403)
.send (JSON.stringify({
errors:[ {message: "api key is unauthorized"} ]
}));
}
}
);
// endpoint for browser graphIQL
app.use('/graphql', graphiqlExpress({
endpointURL: '/client'
}));
app.use("/schema", (req, res) => {
res.set("Content-Type", "text/plain");
res.send(printSchema(schema));
});
But, when I introduce apollo engine
engine.listen({
port: port,
expressApp: fidserver.app,
graphqlPaths: ['/graphql', '/client']
});
everything still works fine - except when I refresh graphiql on the browser with the query as parameters on the browser url.
Then I get this error
{"errors":[{"message":"Unsupported Content-Type from origin: text/html"}]}
Doing the same thing without apollo engine running does not cause an error. If run the query again, or refresh the browser without the query and variable parameters everything works just fine with or without Apollo Engine enabled.
When the error happens I can see from my server log that it's trying to return a react web page containing some javascript for decoding parameters from somewhere but I can't track down from where - it doesn't get as far as hitting any of my code.
This was solved by the guys at Apollo. Here's the answer - I shouldn't have had my graphIQL end point mentioned in the engine.listen options.
Engine should only be placed between the client and the GraphQL server endpoint. Try a config like this:
engine.listen({
port: port,
expressApp: fidserver.app,
graphqlPaths: ['/client'] // removed "graphql"
});

Resources