How to open graphql playground page using apollo server express in 2022? - javascript

We have a API project using express with Apollo server express and graphql, I am new to graphql so I don't know how to land graphql playground page by default.
when I am trying to run it lands on "http://localhost:8080/graphql but it shows
The full landing page can not be loaded; it appears that you might be offline
can any one help me how to land graphql playground page?
I have followed the below code
const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
};
const server = new ApolloServer({ typeDefs, resolvers });
const app = express();
server.applyMiddleware({ app });
const port = 8080;
app.listen({ port }, () =>
console.log(`🚀 Server ready at http://localhost:${port}${server.graphqlPath}`),
);

Install apollo-server-core and add {ApolloServerPluginLandingPageGraphQLPlayground} it from the plugin section
source
https://www.apollographql.com/docs/apollo-server/api/plugin/landing-pages/

Related

Unable to setup Express server on HTTPS

Trying to set up my Express server on HTTPS but unable to access my api. Here is my code:
// server.js
const express = require('express');
const { readFileSync } = require('fs');
const https = require('https');
const app = express();
const key = readFileSync(
'/etc/letsencrypt/live/mydomain.com/privkey.pem',
'utf8'
);
const cert = readFileSync(
'/etc/letsencrypt/live/mydomain.com/fullchain.pem',
'utf8'
);
const ca = readFileSync(
'/etc/letsencrypt/live/mydomain.com/chain.pem',
'utf8'
);
const credentials = { key, cert, ca };
const port = 443
const server = https.createServer(credentials, app);
server.listen(port, () => console.log(`Server is running on port ${port}`));
The error I am receiving is a 502 Bad gateway on all calls to the server.
Everything worked perfectly before when I was running on HTTP like this:
const server = app.listen(8000, () => {});
Beside the URL on my site I can see the padlock icon and it says my site is secure so I believe my certifcate is valid.
Have seen a lot of similar questions posted on here and followed what I've seen in responses. I've even asked chatGPT to check my code and it doesn't see any errors. I've also tried reading my SSL keys as .env variables so I don't think the issue is an incorrect file path.
Can anybody please help me find the solution?
EDIT
Here is an example of a get request I am making to my backend using axios:
const fetchMembers = async () => {
await axios
.get(`/api/total-users`)
};
This invokes a function totalUsers with express.Router from a users file in my routes folder on the backend:
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/total-users', totalUsers);
const totalUsers = async (req, res) => {
try {
const total = await User.find().estimatedDocumentCount();
res.json(total);
} catch (err) {
console.log(err);
}
};
I am using a middleware app.use with a prefix /api and importing the users file to make a connection to my endpoints:
// server.js
const userRoutes = require('./routes/users')
app.use('/api', userRoutes)
While editing this question I tried modifying the middleware prefix to `:443/api' however this still hasn't helped.
Where is User defined inside of routes/users.js? You need to import your DB models before accessing them like this:
const total = await User.find().estimatedDocumentCount();
Otherwise, generally when running fetch('/api...), React will try to access localhost:3000/api instead of localhost:443/api.
React needs to know where to proxy requests to the backend. One way is using the http-proxy-middleware library and by defining a setupProxy.js file.
client/src/setupProxy.js
/**
* Proxy most calls to the server
* #type {Array}
*/
/* eslint-disable #typescript-eslint/no-var-requires */
const { createProxyMiddleware } = require('http-proxy-middleware');
const proxy_urls = ['/api/*';
const target = 'https://localhost:443';
module.exports = function (app) {
proxy_urls.forEach((url) => {
app.use(url, createProxyMiddleware({ target }));
});
};

trying to hide api but backend gives me error

image of the error I am trying to build nft search app that when you give adress it finds the nfts that a wallet has. but i am using alchemy and don't want to expose api key. Don't know backend, using next.js.
my backend code:
const express = require("express");
const axios = require("axios");
const dotenv = require("dotenv");
dotenv.config();
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.get("/api", (req, res) => {
const apiKey = process.env.API_KEY;
const owner = req.query.owner;
const baseURL = `https://eth-mainnet.g.alchemy.com/nft/v2/${apiKey}/getNFTs/`;
const fetchURL = `${baseURL}?owner=${owner}`;
axios
.get(fetchURL)
.then((response) => {
res.json(response.data);
})
.catch((error) => {
res.json({ error: error.message });
});
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
my frontend
const fetchNFTs = async () => {
const response = await fetch(`/api?${wallet}`);
const nfts = await response.json();
setNFTs(nfts);
};
I tried chat gpt, serverless function but I failed to achieve results
Is this a separate Express server? By default Next.js runs on port 3000, and that's why you're making a GET to localhost:3000. But if your Next.js server is started, your custom Express server would pick a different port because the 3000 is going to be taken. So your const response = await fetch('/api?${wallet}'); will result in a 404 because there's no such route in your Next.js app.
You could move your function into a Next.js API handler if you want your backend and frontend to live under the same port. Also you wouldn't need to manually create the express server and take care of the dotenv since Next.js is going to take care of that for you.

I am running into the follow error: Error: Query.totalPosts defined in resolvers, but not in schema

I am running into the error: Error: Query.totalPosts defined in resolvers, but not in schema. I have been looking for a solution but am unable to find a work around or a solution.
my server.js:
const express = require('express')
const {ApolloServer} = require('apollo-server-express');
const http = require('http');
const path = require('path');
const {fileLoader, mergeTypes} = require('merge-graphql-schemas');
require('dotenv').config();
// //resolvers`enter code here
const resolvers = {
Query: {
totalPosts: () => 42,
me: () => 'Gaia'
}
};
const typeDefs = mergeTypes(fileLoader(path.join(__dirname, './typeDefs')));
async function startApolloServer(typeDefs, resolvers){
const apolloServer = new ApolloServer({typeDefs, resolvers});
const app = express();
// typeDefs
// const typeDefs = mergeTypes(fileLoader(path.join(__dirname, './typeDefs')));
await apolloServer.start();
//this method connects Apollo server to a specific HTTP framework ie: express
apolloServer.applyMiddleware({app, path: '/graphql'});
apolloServer.applyMiddleware({ app });
const httpserver = http.createServer(app);
// rest endpoint
app.get('/rest', function(req, res) {
res.json({
data: 'hit rest endpoint'
});
});
app.listen(process.env.PORT, function() {
console.log(`Server running at http://localhost:${process.env.PORT}`);
console.log(`Graphql server running at http://localhost:${process.env.PORT}${apolloServer.graphqlPath}`);
});
};
startApolloServer(typeDefs, resolvers);
Your field totalPosts exist in typeDef ?
As documentation said in step 3, https://www.apollographql.com/docs/apollo-server/getting-started/ , you have to define your graphql schema for use it.
Every GraphQL server (including Apollo Server) uses a schema to define the structure of data that clients can query. In this example, we'll create a server for querying a collection of books by title and author.
You should type something like this :
type Query {
totalPost: Int
me: String
}
And, when i build a graphql api on nest.js, schema file automaticly build. I guess, it's same way with express.
Did you try to setup your api following this doc : https://www.apollographql.com/docs/apollo-server/v2/integrations/middleware
typeDef look like automaticly resolve and push to a schema file. You may re-load your serve when it's should be update.
const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const { typeDefs, resolvers } = require('./schema');
async function startApolloServer() {
const app = express();
const server = new ApolloServer({
typeDefs,
resolvers,
});
await server.start();
server.applyMiddleware({ app });
app.use((req, res) => {
res.status(200);
res.send('Hello!');
res.end();
});
await new Promise(resolve => app.listen({ port: 4000 }, resolve));
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
return { server, app };
}

NextJS throwing 404 when deployed to Vercel

I have a custom express server that I'm using with NextJS.
Everything works just fine when I'm developing locally, but when I deploy to Vercel, I catch 404s whenever I try to access my backend API.
What could be going wrong? Here's my server.ts:
import express from 'express';
import next from 'next';
import bodyParser from 'body-parser';
import { connectDbs } from './config/db';
import { listingsRouter } from './routes';
const PORT = process.env.PORT || 3003;
const dbs = ['mydb'];
const dev = process.env.NODE_DEV !== 'production';
const nextApp = next({ dev });
const handle = nextApp.getRequestHandler();
const applyMiddleware = (app) => {
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
};
const applyRoutes = (app) => {
app.use('/api/listings', listingsRouter);
};
const startServer = async () => {
await nextApp.prepare();
const app = express();
applyMiddleware(app);
applyRoutes(app);
app.get('*', (req, res) => handle(req, res));
await connectDbs(dbs);
app.listen(PORT, () => console.log(`App listening on port ${PORT}`));
};
startServer();
The Next.js documentation for custom servers:
A custom server cannot be deployed on Vercel, the platform Next.js was made for.
Source: Custom Server
Even though you can't deploy a custom server, you generally don't need to do so because Next.js supports Serverless Functions using the /pages/api directory.
Source: API Routes
Also take a look at this Guide explaining how to convert custom Next.js server to routes:
Source: Server to Routes Guide

Heroku working differently than running locally

I created a Nuxt app with express backend, and i have registered some api routes. When i run locally as production npm run build && npm run start it works just fine.
Here it is working locally
However when i run it with heroku heroku local web all the API routes throw a 404.
Here it doesn't work with heroku
Here is my server code
require('dotenv').config();
const express = require('express');
const consola = require('consola');
const { Nuxt, Builder } = require('nuxt');
const bodyParser = require('body-parser');
const session = require('express-session');
const mongoose = require('mongoose');
const cors = require('cors');
mongoose.Promise = Promise;
mongoose.set('useFindAndModify', false);
mongoose.connect(process.env.MONGODB_CONNECTION_STRING);
const app = express();
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js');
config.dev = process.env.NODE_ENV !== 'production';
async function start() {
// Init Nuxt.js
const nuxt = new Nuxt(config);
const { host, port } = nuxt.options.server;
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
} else {
await nuxt.ready();
}
app.use('/api', require('./routes'));
// session
app.use(
session({
sessionDataHere
})
);
// enable cors
app.use(cors());
// body parser
app.use(bodyParser.json());
app.use((error, req, res, next) => {
console.error(error.response);
res.status(500).send(error);
});
// Give nuxt middleware to express
app.use(nuxt.render);
// Listen the server
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
});
}
start();
And here is the index of my routes
const { Router } = require('express');
const authRouter = require('./auth');
const videoRouter = require('./video');
const baseRouter = Router();
baseRouter.use('/', authRouter);
baseRouter.use('/', videoRouter);
baseRouter.get('/test', (req, res) => res.send('This is working!'));
module.exports = baseRouter;
Maybe i'm missing something on the heroku configuration? Thanks!
Ok, i fixed it. I had to change my procfile. It was running nuxt start not npm start so it wasn't running any of the server side code

Categories