Apollo Client can't query in getServerSideProps but works on client [closed] - meteor

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
In our Nextjs app we are connecting to a different domain for Apollo Server, queries work fine on the client with cors options and everything. However same queries fails with network fetch error inside getServerSideProps.
I have tried changing headers on the createApolloClient and using fetch with isomorphic-unfetch however there is no response from server side calls to the graphql server.
Our apollo client code is same as the nextjs example on here except the httpLink part we use it like the following
const httpLink = new HttpLink({
uri: 'http://localhost:3000/graphql',
fetchOptions: {
mode: 'cors',
},
credentials: 'include',
fetch: enhancedFetch,
});
and this is the server configutaion
const server = new ApolloServer({
schema,
validationRules: Meteor.isDevelopment ? [depthLimit(10)] : [NoIntrospection, depthLimit(10)],
context: async ({ req }) => ({
user: await getUser(req.headers.authorization),
}),
cache: 'bounded',
uploads: false,
plugins: Meteor.isDevelopment ? [ApolloServerPluginLandingPageGraphQLPlayground({})] : [],
csrfPrevention: true, // Enable CSRF prevention
});
async function startApolloServer() {
await server.start();
server.applyMiddleware({
app: WebApp.connectHandlers,
path: 'http://localhost:3000/graphql',
cors: {
origin: 'http://localhost:4000',
credentials: true,
},
});
}
When NextJS sends a query form getServerSideProps it receives an error as the following
{
"name": "ApolloError",
"graphQLErrors": [],
"clientErrors": [],
"networkError": {
"cause": {
"errno": -61,
"code": "ECONNREFUSED",
"syscall": "connect",
"address": "::1",
"port": 3000
}
},
"message": "fetch failed"
}

Related

Post multiple logs to DataDog with 1 HTTP request

I want to post multiple logs to DataDog from a JS function, using a single HTTP request. Looking at the v2 docs for DataDog's 'send logs' POST endpoint, it sounds like this is possible:
For a single log request, the API ... For a multi-logs request, the API ...
But it's not clear to me from the docs how to actually send a 'multi-logs' request. I've tried the following:
const dataDogEndpoint = 'https://http-intake.logs.datadoghq.com/api/v2/logs';
const body = {
ddtags: 'env:production,status:info',
hostname: 'my-host',
message: ['My first production log.', 'My second production log.'],
service: 'my-service'
};
const response = await fetch(dataDogEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'DD-API-KEY': apiKey
},
body: JSON.stringify(body)
});
Perhaps unsurprisingly, this appears in DataDog as a single log with the following content:
[My first production log., My second production log.]
How can I achieve this?
Got it - this can be achieved by adding multiple log objects to the body like so:
const dataDogEndpoint = 'https://http-intake.logs.datadoghq.com/api/v2/logs';
const body = [{
ddtags: 'env:production,status:info',
hostname: 'my-host',
message: 'My first production log.',
service: 'my-service'
},{
ddtags: 'env:production,status:info',
hostname: 'my-host',
message: 'My second production log.',
service: 'my-service'
}];
const response = await fetch(dataDogEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'DD-API-KEY': apiKey
},
body: JSON.stringify(body)
});
(You'll probably want a loop instead of instantiating each log object separately.)

Apollo client cache with SSR

I am using #apollo/client with Next.js Server Side Rendering. The data I am fetching is from wp-graphql, and therefore it is crucial to have them rendered on server side. There is just one slight issue, the cache is forever. I either have to reset the cache every x minutes:
setInterval(async () => {
await client.resetStore();
}, 60_000);
or specify the no-cache policy
const client = new ApolloClient({
uri: "https://the.url",
cache: new InMemoryCache({}),
// For no cache, which is slow
defaultOptions: {
watchQuery: {
fetchPolicy: "no-cache",
errorPolicy: "ignore",
},
query: {
fetchPolicy: "no-cache",
errorPolicy: "all",
},
},
});
Is there any better way to do this, while still using SSR?

Express cookie parser is not creating cookies in production

I am using graphql-yoga and I am writing cookies that access the Microsoft Graph API. On the front end I have an apollo client with NextJS set up and it is working perfectly... in development. When I deploy the server there is no recognition of the cookies from the front end at all. In my reading I think this has something to do with NextJS being server rendered (even though when I run next build it says static build...) I am certain the problem is somewhere in here (I am leaving the comments in, to show all of the places I tried to set the credentials to 'include')
export default function createApolloClient(initialState, ctx) {
// The `ctx` (NextPageContext) will only be present on the server.
// use it to extract auth headers (ctx.req) or similar.
return new ApolloClient({
ssrMode: Boolean(ctx),
link: new HttpLink({
fetch,
uri: process.env.NODE_ENV === 'development' ? endpoint : prodEndpoint,
credentials: 'include', // Additional fetch() options like `credentials` or `headers`
fetchOptions: {
credentials: 'include',
},
// request: operation => {
// operation.setContext({
// fetchOptions: {
// credentials: 'include',
// },
// });
// },
}),
connectToDevTools: true,
// credentials: 'include',
cache: new InMemoryCache().restore(initialState),
});
}
The other answers to this all involved CORS, but I have CORS set up on my my GraphQL-Server:
const opts = {
debug: process.env.NODE_ENV === 'development',
cors:
process.env.NODE_ENV === 'development'
? {
credentials: true,
origin: ['http://localhost:3000'],
}
: {
credentials: true,
origin: [
'...'
],
},
};
server.start(opts, () =>
console.log('Playground is running on http://localhost:4000'),
);
Can anyone point me in the right direction? Am I right to be looking at the ApolloClient portion of my front end? Thanks in advance.
This was staring me in the face, but they warnings were being drowned out in the console. Cookies need to be set with in Chrome.
{
...,
sameSite: false,
secure: true
}
The console had these links to provide insight:
https://www.chromestatus.com/feature/5088147346030592
https://www.chromestatus.com/feature/5633521622188032
This is a very recent change in Chrome, and I only realized that there was a difference because I randomly opened my site in Firefox, and it worked.

Axios post request to Firebase Auth REST API produces 400 error

I have an instance of Axios:
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://identitytoolkit.googleapis.com/v1'
});
export default instance;
Then I import it in my signup.vue file:
<script>
import axios from '../../axios-auth';
...
</script>
In that Vue file I have a signup form, which runs the following method once I hit the Submit button:
onSubmit() {
const formData = {
email: this.email,
age: this.age,
password: this.password,
confirmPassword: this.confirmPassword,
country: this.country,
hobbies: this.hobbyInputs.map(hobby => hobby.value),
terms: this.terms
};
console.log(formData);
axios.post('/accounts:signUp?key=my_key_goes_here', {
email: formData.email,
password: formData.password,
returnSecureToken: true
})
.then(res => {
console.info(res);
})
.catch(error => {
console.error(error);
});
}
I'm getting a 403 error - forbidden 400 error - bad request.
I tried to change headers:
instance.defaults.headers.post["Access-Control-Allow-Origin"] = "localhost";
instance.defaults.headers.common["Content-Type"] = "application/json";
But that didn't help.
I'm working from localhost and I saw that localhost is allowed by default. I tried also to add 127.0.0.1 to the list, but that also didn't help.
What am I missing? How can I make this request work?
If you get a 400 error it is maybe because you get an error from the API itself:
Common error codes
EMAIL_EXISTS: The email address is already in use by another account.
OPERATION_NOT_ALLOWED: Password sign-in is disabled for this project.
TOO_MANY_ATTEMPTS_TRY_LATER: We have blocked all requests from this device due to unusual activity. Try again later.
As a matter of fact, those errors return an HTTP Status Code of 400.
You can see the exact response message (e.g. EMAIL_EXISTS) by doing the following with axios:
axios.post('/accounts:signUp?key=my_key_goes_here', {
email: formData.email,
password: formData.password,
returnSecureToken: true
})
.then(res => {
console.info(res);
})
.catch(error => {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
} else if (error.request) {
console.log(error.request);
} else {
console.log("Error", error.message);
}
});
See https://github.com/axios/axios#handling-errors
I agree with you as i have tried many approaches but was not getting the result. Hence i have tried to change the code.
You need to make two changes in your code.
1] You need to comment the instance.defaults.headers.post["Access-Control-Allow-Origin"] = "localhost"; because you are providing the authentication globally. As, firebase provides the feature of authentication and you are connecting the web app with REST API.
2] You need to add { headers: {'Content-Type': 'application/json' } in the axios.post() method to prevent it from CORS Error.
Following this approach i hope you can get the respective output.
Happy Coding!
Directly call
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[yourkey]
No need to keep it in a separate file
Anyone who comes to the thread in future. I faced this issue and lost in debugging and worked with fetch. It was tiresome and took me a day but i made axios work. Here is the code.
const data = JSON.stringify({
idToken: authContext.token,
password: enteredNewPassword,
returnSecureToken: false,
});
// Send the valid password to the endpoint to change password
axios
.post(
"https://identitytoolkit.googleapis.com/v1/accounts:update?key=[Your Key]",
data,
{
headers: {
"Content-Type": "application/json",
},
}
)
.then((response) => {
console.log(response.data);
})
.catch((err) => {
console.log(err.message);
});
Remember to Stringify the data you want to send. Stringify it outside of the http request and then pass that variable. Don't know why but this helps!
Lastly remember to add the header when sending the request to firebase. Make sure axios.post is on the same line. My formatter gave a line break which was also cause of error.
Hope it helps :)

Meteor + Apollo Subscription: Websocket connection closed

I'm using meteor and trying to make Apollo Subscriptions to work, but I'm getting
WebSocket connection to 'ws://127.0.0.1:3000/sockjs/401/m892wugm/websocket' failed: Connection closed before receiving a handshake response in the client.
I followed apollographql.com guide for Server Configuration and Client Configuration but I'm not quite sure how to connection the client to the server yet.
In the client, I'm using ApolloClient and ApolloLink to pass the Meteor auth to GraphQL.
Here's the code:
Client
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloLink } from 'apollo-link'
const httpLink = new createHttpLink()
const authLink = new ApolloLink((operation, forward) => {
operation.setContext(() => ({
headers: { 'meteor-login-token': Accounts._storedLoginToken() },
}))
return forward(operation)
})
export default ApolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
})
Server
createApolloServer({
schema,
tracing: true,
cacheControl: true,
})
new SubscriptionServer({
schema,
execute,
subscribe,
}, {
server: WebApp.httpServer,
path: '/subscriptions',
})
Package.json (not everything, of course)
Meteor 1.6.1.1
...
"apollo-client": "^2.2.5",
"apollo-link": "^1.2.1",
"apollo-link-context": "^1.0.7",
"apollo-link-http": "^1.5.3",
"apollo-link-ws": "^1.0.8",
"subscriptions-transport-ws": "^0.9.9",
...
I read somewhere that passing noServer: true to the SubscriptionServer() resolve the conflict. The error indeed goes away, but the subscription doesnt seem to work either.
And yes, I have followed the Meteor Integration guide from apollographql, but the info there is outdated and does not work.

Resources