I am trying to send POST/GET requests after using firebase serve, but this always responds in an error. I have tried many things like reinstalling node, using a backslash at the end of the url, using firebase deploy instead, resetting firebase.json, using ThunderClient in vscode instead of Postman, turning off ssl certificate for Postman, etc.
Here is my index.js file:
const functions = require("firebase-functions");
const express = require("express");
const app = express();
const Auth = require("./util/middleware");
// enable CORS
const cors = require("cors");
app.use(cors());
// can't use app level middleware :(
// app.use(Auth);
const { signup, login, logout } = require("./handlers/users");
const {
getMyBoardsOverview,
getLeaderboard,
createBoard,
} = require("./handlers/boards");
// user routes
app.post("/signup", signup);
app.post("/login", login);
app.post("/logout", Auth, logout);
// board routes
app.get("/boards", Auth, getMyBoardsOverview);
app.get("/board/:boardId/leaderboard", Auth, getLeaderboard);
app.post("/board", Auth, createBoard);
exports.api = functions.region("us-west2").https.onRequest(app);
Related
Well currently I am disallowing all file uploads to routes by setting up the server like:
const upload = multer();
const server = express();
module.exports = () => {
// ...
server.use(logger('dev'));
server.use(express.json());
server.use(express.urlencoded({ extended: false }));
server.use(express.raw());
server.use(cookieParser());
server.use(express.static(path.join(projectRoot, 'public')));
server.set('trust proxy', 1);
server.use(upload.none());
server.use('/', router);
// ...
}
Which correctly blocks all files. Now I wish to allow uploading files only in the POST request to /test:
import * as express from "express";
import multer from "multer";
const upload = multer({storage: multer.memoryStorage()});
const router = express.Router();
router.post('/test', upload.single('pdf'), function(req, res, next) {
const r = 'respond with a test - POST';
res.send(r);
});
However when I try to use this in postman I get the error "multerError", "LIMIT_UNEXPECTED_FILE" for the field 'pdf'. I notice that if I remove the line server.use(multer.none()) it works, but then I can upload files to any place anyways, not exactly what I like?
Nothing will be uploaded to your server unless you specify a multer middleware on the entire server, on a route, or on a particular path. So you can safely remove the server.use(upload.none());.
The middleware will then not try to consume the payload of the incoming request. How much load the receiving (without consumption) of the payload causes on the server, I don't know, but you could theoretically destroy the connection whenever the client tries to submit a payload:
req.on("data", function() {
req.destroy();
});
But perhaps the creation of new connection afterwards causes more load on the server overall.
I am not able to load swagger for my nestJS application which is deployed on EKS.
Here is my main.ts
import {NestFactory} from '#nestjs/core';
import {NestExpressApplication} from '#nestjs/platform-express';
import {DocumentBuilder, SwaggerModule} from '#nestjs/swagger';
const swaggerUi = require('swagger-ui-express')
import {AppModule} from './app.module';
import {json, NextFunction, Request, Response} from 'express';
(async () => {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const options = new DocumentBuilder()
.setTitle('Test')
.build();
const document = SwaggerModule.createDocument(app, options,{ ignoreGlobalPrefix: true
app.use("*/docs",swaggerUi.serve,swaggerUi.setup(document));
// Or
SwaggerModule.setup(`/docs`, app, document);
await app.listen(port, () => {
console.log(`Test service is running on port ${port}...`);
});
})
();
On my local machine the swagger doc loads correctly but when I deploy it to a development environment, it fails
dev url "https://dev-test-api.com/testservice/v1/docs/", it strips the /testservice/v1/ and redirects to "https://dev-test-api.com/docs/ and gives a 404.
I have tried couple of solutions mentioned in https://github.com/scottie1984/swagger-ui-express/issues/183
The forward-prefix option and the redirect too. None seem to work
Another problem I have is that the prefix "testservice/v1" changes as per different sandbox environments and since it is not an environment variable I don't have a way to set the path for swagger file before app is loaded.
I'm trying to follow this guide to setup testing an express API in Insomnia. I have setup a poretected route at http://localhost:5000/api/v1/private/dashboard with express-openid-connect. I have also setup an machine-to-machine application and API in auth0.
When in Insomina I try to access http://localhost:5000/api/v1/private/dashboard I am redirected to the universal login page. Trying to login does nothing. I don't think I've set this up right, but am strugging to understand the process and can't find a similar issue when searching.
I want to be able to make GET/POST/PUT/DELETE requests in Insomnia and the data be returned the same as unauthenticated routes.
I have tried various configuration changes including using client credentials, in body, using a different app type but I don't really understand auth0's configuration so don't know what I'm doing.
server.js (where the authenication check is called via oidc)
import express from "express";
import oidc from "express-openid-connect";
import publicRoutes from "./routes/publicRoutes.js";
import privateRoutes from "./routes/privateRotues.js";
const app = express();
const {
auth,
requiresAuth,
} = oidc;
const config = {
authRequired: false,
auth0Logout: true,
secret: process.env.SECRET,
baseURL: process.env.BASE_URL,
clientID: process.env.CLIENT_ID,
issuerBaseURL: process.env.ISSUER_BASE_URL,
};
console.log(config);
app.use(auth(config));
app.use("/api/v1/public", publicRoutes);
app.use("/api/v1/private", requiresAuth(), privateRoutes);
app.use("*", (req, res) => res.status(404).json({error: "File not found"}));
export default app;
I made a UI with React Native, as well as a Cheerio.js scraper (with Cron Job to activate it once every day) I'll use to grab certain data from the web, so it can render in the UI. However, I have no idea how to link the two of them.
I am pretty sure I can do this with Express (which I am most comfortable with for the back-end), but can someone tell me exactly what I need to do to connect my front-end to a back-end?
Just in case, I am a junior dev (better on the front-end than the back-end) so please keep your answers simple. Even if your answers are more conceptual, rather than code-based, I'd really appreciate it.
API
I'm quite happy with GraphQL as an alternative to REST. However, there are many ways to connect through an api. Your client needs the link to where your server is running, and your server needs to enable that.
Tutorials
I think I couldn't explain it better than this tutorial (with example on Github): https://medium.com/react-native-training/react-native-with-apollo-server-and-client-part-1-efb7d15d2361
https://medium.com/react-native-training/react-native-with-apollo-part-2-apollo-client-8b4ad4915cf5
And following Stephen Grider's tutorial on Udemy for deeper understanding of GraphQL. He is using React and not React Native in his tutorial but the syntax remains very close.
https://www.udemy.com/graphql-with-react-course/learn/v4/overview
Important notice - The first tutorials use "apollo-server" while udemy's tutorial uses graphql. apollo-server changes quite often and graphql may be clearer.
Example
Here's how my bridge between the two looks like. The biggest difficulty was dealing with Cors for the front-end version of the app (Next.js) and finding out that the server can be accessed on http://10.0.3.2:8080/graphql (may vary) instead of localhost:8080.
My index.android.js (client side):
import React from 'react'
import { AppRegistry } from 'react-native'
import App from './app'
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { ApolloProvider } from 'react-apollo'
const Client = () => {
const networkInterface = createNetworkInterface({
uri: 'http://10.0.3.2:8080/graphql'
})
const client = new ApolloClient({
networkInterface
});
return (
<ApolloProvider client={client}>
<App />
</ApolloProvider>)
}
AppRegistry.registerComponent('apolloclient', () => Client);
My app.js server side
const express = require('express');
// const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
const chalk = require('chalk');
// New imports
// NEVER FORGET to require the models,
// in which schemas are registered for a certain model
// forgetting it would throw "Schema hasn't been registered for model..."
const models = require('./models');
const expressGraphQL = require('express-graphql');
const schema = require('./schema/schema');
const app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// My mongoLab URI
const MONGO_URI = 'mongodb://xxx:xxx#xxx.mlab.com:xxx/xxx';
// mongoose's built in promise library is deprecated, replace it with ES2015 Promise
mongoose.Promise = global.Promise;
// Connect to the mongoDB instance and log a message
// on success or failure
mongoose.connect(MONGO_URI);
mongoose.connection.once('open', () => console.log(`${chalk.blue(`🗲 Connected to MongoLab instance 🗲`)}`));
mongoose.connection.on('error', error => console.log(`${chalk.yellow(`âš Error connecting to MongoLab: ` + error + ` âš `)}`));
app.use(cors());
// We pass the schema as an option to our expressGraphQL middleware
app.use('/graphql', expressGraphQL({
schema,
graphiql: true
}))
module.exports = app;
my index.js (server side):
const app = require('./app');
const chalk = require('chalk');
const PORT = 8080;
app.listen(PORT, () => {
console.log(`${chalk.green(`✔ Server started on http://localhost:${PORT} ✔`)}`);
});
Assuming you're communicating with an API built with Express then use fetch as described in the docs: https://facebook.github.io/react-native/docs/network.html
quick question regarding using React-Router. I'm having trouble getting my server to handle pushState (if this is the correct term). Originally, I was using a module called connect-history-api-fallback, which was a middleware that enabled me to only server up static files form my dist directory. Visiting the client www.example.com obviously worked and I could navigate throughout the site, additionally, refreshing at any route like www.example.com/about - could also work.
However, I recently added one simple API endpoint on my Express server for the React app/client to ping. The problem now is that while I can get the initial page load to work (and thus the /api/news call to work, to fetch data from a remote service), I can no longer do a refresh on any other routes. For example, now going to www.example.com/about will result in a failed GET request for /about. How can I remediate this? Really appreciate the help! PS - not sure if it matters, but I'm considering implementing Server Side Rendering later on.
import express from 'express';
import historyApiFallback from 'connect-history-api-fallback';
import config from '../config';
import chalk from 'chalk';
import fetch from 'node-fetch';
import path from 'path';
const app = express();
// FIXME: Unsure whether or not this can be used.
// app.use(historyApiFallback({
// verbose : true
// }));
//// DEVELOPMENT MODE ONLY - USING EXPRESS + HMR ////
/* Enable webpack middleware for hot module reloading */
if (config.get('globals').__DEV__) {
const webpack = require('webpack');
const webpackConfig = require('../build/webpack/development_hot');
const compiler = webpack(webpackConfig);
app.use(require('./middleware/webpack-dev')({
compiler,
publicPath : webpackConfig.output.publicPath
}));
app.use(require('./middleware/webpack-hmr')({ compiler }));
}
//// PRODUCTION MODE ONLY - EXPRESS SERVER /////
if (config.get('globals').__PROD__) {
app.use(express.static(__dirname + '/dist'));
}
//// API ENDPOINTS FOR ALL ENV ////
app.get('/api/news', function (req, res) {
fetch('http://app-service:5000/news')
.then( response => response.json() )
.then( data => res.send(data) )
.catch( () => res.sendStatus(404) );
});
// Wildcard route set up to capture other requests (currently getting undexpected token '<' error in console)
app.get('*', function (req, res) {
res.sendFile(path.resolve(__dirname, '../dist', 'index.html'));
});
export default app;
Express works by implementing a series of middleware that you "plug in" in order via .use. The cool thing is your routes are also just middlware — so you can separate them out, have them before your history fallback, and then only requests that make it past your routes (e.g., didn't match any routes) will hit the fallback.
Try something like the following:
const app = express();
// ...
var routes = exprss.Router();
routes.get('/api/news', function (req, res) {
fetch('http://app-service:5000/news')
.then( response => response.json() )
.then( data => res.send(data) )
.catch( () => res.sendStatus(404) );
});
app.use(routes);
app.use(historyApiFallback({
verbose : true
}));