How to log HTTP request and response with ApolloClient - javascript

I'm using both ApolloClient from 'apollo-client' and 'apollo-boost' libraries, like
const client = new ApolloClient({
uri: 'https://www.myapp.no/api/',
request: async (operation) => {
console.log(operation)
operation.setContext({
headers: {
authorization: tokenHeader,
'Content-Type': 'application/json'
}
})
},
onError: (error) => {
if (error.graphQLErrors) {
console.log('ApolloClient graphQLErrors')
console.log(graphQLErrors)
}
if (error.networkError) {
console.log('ApolloClient networkError')
console.log(graphQLErrors)
}
}
})
The operation object only show variables and query information. How to log the actual HTTP requests and response under the hood?
I want to see the outgoing request headers and params, and the responses headers and status code
This seems like a very simple task but I've spent quite some time searching without any mentions about this.

You can use this awesome extension: https://github.com/apollographql/apollo-client-devtools

Related

How to use POST api token to use third party APIs in nextjs

I need to POST to a third party api route to receive an access token to be authorized to fetch data from their endpoints, but I'm not sure how to use the token. They are using Swagger:
export default async function() {
const res = await fetch('url', {
method:'POST',
headers: {
accept: 'application/json'
}
});
const data = await res.json()
console.log(data)
}
I get in response:
{
access_token: 'my token...',
...
}
But I'm not sure how I'd use this response to authorize fetching data. Do I need to pass the token to the headers in the fetch?
export async function getStaticProps() {
const res = await fetch( `url`, {
headers: {
accept: 'application/json',
}
});
const data = await JSON.stringify(res);
return {
props: {
items: data
},
};
}
I can't seem to find much info on this, or I'm just searching for the wrong things. I'm not sure if I'm understanding this correctly
Likely you'll need to send that token in an Authorization header with the request, something like this:
const res = await fetch(`url`, {
headers: {
accept: 'application/json',
Authorization: `Bearer ${token}`,
}
});
const json = await res.json()
const data = JSON.stringify(json);
The API docs should be able to tell you specifics though, if you're still having issues please post the API docs if they're public!

Fastify inject test with jest timing out when sending text/plain body

I have the following basic fastify server:
import Fastify from 'fastify';
import expressPlugin from 'fastify-express';
import cors from 'cors';
async function build() {
const fastify = Fastify();
await fastify.register(expressPlugin);
fastify.use(cors());
fastify.post(
'/someurl',
async (request, reply) => {
console.log('PATATAPATATA');
void reply.send({message: "Hey, I'm stuck :D"})
}
);
return fastify;
}
And then I have the following test:
it.only('Should reply with a 200 status code when sending a string body', async () => {
// after this line, jest gives a timeout (5000 ms)
const response = await getResponse({
headers: {
Accept: 'application/json',
'Content-Type': 'text/plain',
'Content-Length': 1,
},
payload: 'a',
});
expect(response.statusCode).toEqual(200);
});
async function getResponse(options?: InjectOptions) {
const app = await build();
return app.inject({
method: 'POST',
url: `/someurl`,
...options,
});
}
The content-length header should not be needed, but I have added it after trying different things to fix it. If you delete it you get the timeout anyway. Any idea why this is happening? If I delete the content-type header then I get a 415 http error.
Side note: the code console.log('PATATAPATATA'); is never executed, so the problem has to be in some fastify internals or the light my request module.
Update It seems this only happens when I use payload in the inject options, like this:
async function getResponse(options?: InjectOptions) {
const app = await build();
return app.inject({
method: 'POST',
url: `/someurl`,
payload: {},
});
}
I have also discovered that:
Using payload: '' works.
Using payload: '{}' does not work. It does not give a timeout, but it does not run the post method either.
Using payload: '{}' and content-type set to application/json or text/plain, also gives the timeout.
It seems fastify-express it's not compatible with inject -> https://github.com/fastify/fastify/issues/3739

cross origin for amazon lambda function from localhost in gatsby site

I have the following code which works when I run it as a local serverless function with netlify dev, but I need it to run cross origin from a dev server to the hosted server function. I put the function in a aws lambda function but I am getting a cross origin blocked error on my https:dev.website.com, I thought I have the correct headers in the return object so not sure why I am getting a cross origin error.
Any help would be great
const sanityClient = require("#sanity/client");
const client = sanityClient({
projectId: "random-id",
dataset: "production",
useCdn: true,
});
exports.lambdaHandler = async (event, context) => {
var body = JSON.parse(event.body);
//console.log(body.price_id)
try {
const checkPriceId = async (test) => {
const query = `*[_type == "products" && price_id == "${body.price_id}"]`;
const documents = await client.fetch(query, {}); // this could throw
return documents.map((document) => document.sold);
};
var ok = checkPriceId().then((test) => {
return new Promise(function (resolve, reject) {
//console.log(test) // this will log the return value from line 7
console.log(test);
resolve(test);
});
});
var bools = await ok;
// prettier-ignore
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods':'GET, POST, OPTION',
},
body: JSON.stringify({
sold: bools,
}),
};
} catch (err) {
return { statusCode: 500, body: err.toString() };
}
};
This is my request to the function if that helps
var fetchUrl = https://random.executue-api.aws.com/prod/sold //not exact
var fetchData = async function () {
const response = await fetch(fetchUrl, {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
price_id: final,
}),
})
.then(res => {
return res.json()
})
.catch(error => console.log(error))
return response
}
Update:
I tried adding cors the way suggested in the answer below, but it failed seen below so I tried manually adding the method response seen after.
I still get a cross domain error. And I have changed the domain so it is now https as well. Really stuck here.
I was looking into this more, and it seems like before it does the actual post it does a cors check at the options method, so I added in the same access control headers, and deployed but did not work. Don't quite get this.
Your headers look ok to me. (note: If you mix HTTP and HTTPS you are most likely to get a mixed content error in the client). If it is ONLY a CORS issue that you are seeing in the console in the web browser, then you might not have configured the API Gateway correctly in AWS.
In AWS, go to API Gateway and you should see something like the below:
Make sure that you enable CORS and then redeploy.
UPDATE:
Just looking at a previous implementation of a lambda function I setup with AWS. The headers I declared were as follows:
headers: {
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"Allow" : "GET, OPTIONS, POST",
"Access-Control-Allow-Methods" : "GET, OPTIONS, POST",
"Access-Control-Allow-Headers" : "*",
"Access-Control-Allow-Credentials" : true
}
Your headers look OK to me though. However, when you created the method in the API Gateway, did you select Use Proxy Lambda Integration? (see screenshot).
Your client side fetch request looks ok. For reference mine was:
const url = 'your url';
const options = {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
};
fetch(url, options).then(res => res.json());
Unrelated to this issue, but its not advisable to mix Async/Await with .then promise chaining. But this isn't the issue you are having. Just something to note.
Check the values from your Integration Response / try setting them manually for both OPTIONS and POST (and if that works, make sure you are passing through the response correctly from the lambda).
Your POST action should only require the Access-Control-Allow-Origin header. The other two (Access-Control-Allow-Methods, Access-Control-Allow-Headers) belong in the OPTION action. See this writeup, and note the full example exchange for a preflighted request (in grey): https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests

Typescript removes Authorization header from POST and PATCH fetch requests

I've built an API using C# that uses JWT tokens for authorization. On the frontend I store these tokens in local storage and get them, when creating a request. When creating GET or DELETE requests, everything works fine, and using console.log() I can see that fetch options have the Authorization header added. However when using POST or PATCH methods, the Authorization header is missing immediatly after adding it to the object. Here is my request method:
const send = async (apiOptions: ApiParams): Promise<FetchReturn> => {
const accessToken = GetAccessToken()
const options: ApiOptions = {
method: apiOptions.method,
headers: {
Authorization: `Bearer ${accessToken}`
}
}
console.log(options)
if (apiOptions.data) {
options.headers = {
'Content-Type': 'application/json'
}
options.body = JSON.stringify(apiOptions.data)
}
const result = await fetch(`${getUrl()}/${apiOptions.path}`, options).then(res => res).catch(err => err)
if (!result.ok) {
if (IsExpired()) {
const refreshResult = await fetch(`${getUrl()}/api/user/refresh`, {method: 'POST', headers:{
'Content-Type': 'application/json'
}, body: JSON.stringify(GetRefreshRequest())}).then(res => res).catch(err => err)
if (refreshResult.ok) {
Login(JSON.parse(await refreshResult.text()))
return await send(apiOptions)
} else if (refreshResult.status === 401) {
Logout()
window.location.reload()
return { code: 0, text: ""}
}
}
}
const text = await result.text()
return { code: result.status, text: text }
}
I suppose that in apiParams for POST you have property 'data' assigned, and later you have if-condition that completely replaces request headers object.
Change it to:
options.headers['Content-Type'] = 'application/json';
To keep authorization in headers
The first time check your apiOptions.data
i think , its null when you call POST/Patch request
Just put console.log("...") In the if statement , Then try for resolve your Error
If your problem not resolved, put a replay under my post

Unable to send get request with headers using axios

Able to get the response in postman. But unable to get in axios. Getting html as response. What would be the problem?
import axios from 'react-native-axios';
var config = {
headers: {
'Content-Type': 'Application/Json',
'JsonStub-User-Key': '__USER__KEY',
'JsonStub-Project-Key': '__PROJECT__KEY'
}
};
export async function menuListByCategories() {
// simulate an asynchronous operation
const url = "http://jsonstub.com/burgers";
axios.get(url, {config})
.then((response) = > {
console.log(response.data);
})
.
catch ((error) = > {
console.log("axios error:", error);
});
}
Update: check the response of this code
You can add data: {} in config in order not to have Content-Type removed by axios. Check the answer of the question below.
Jsonstub response not showing

Categories

Resources