i'm very new of Express and server side in general, for my small react messaging app i'm using Express for the backend(a json file) and webpack dev server for frontend.
If i start just the Webpack server, the app show correctly, probelems come when i try to make the two works together and i think the problem is the proxy configuration of webpack-dev-server.
Here is my express server, json-api-server.js:
var express = require('express');
var serveStatic = require('serve-static');
var fs = require('fs');
var path = require('path');
var bodyParser = require('body-parser');
module.exports = (PORT) => {
const MESSAGES_FILE = path.join(__dirname, 'src/app/data/messages.json');
const app = express();
app.use(serveStatic(__dirname + '/build'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// Additional middleware which will set headers that we need on each request.
app.use(function(req, res, next) {
// Set permissive CORS header - this allows this server to be used only as
// an API server in conjunction with something like webpack-dev-server.
res.setHeader('Access-Control-Allow-Origin', '*');
// Disable caching so we'll always get the latest comments.
res.setHeader('Cache-Control', 'no-cache');
next();
});
app.get('/messages', function(req, res) {
fs.readFile(MESSAGES_FILE, function(err, data) {
if (err) {
console.error(err);
process.exit(1);
}
res.json(JSON.parse(data));
});
});
app.post('/messages', function(req, res) {
fs.readFile(MESSAGES_FILE, function(err, data) {
if (err) {
console.error(err);
process.exit(1);
}
var messages = JSON.parse(data);
var newMessage = {
id: Date.now(),
body: req.body.body,
date: req.body.date,
from: req.body.from,
to: req.body.to
};
messages.push(newMessage);
fs.writeFile(MESSAGES_FILE, JSON.stringify(messages, null, 4), function(err) {
if (err) {
console.error(err);
process.exit(1);
}
res.json(messages);
});
});
});
app.listen(PORT, function (err) {
if (err) {
return console.log(err);
}
console.log('Listening at' + PORT );
});
}
This is webpack-server.js:
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
module.exports = (PORT) => {
const backendPort = PORT - 1;
const server = new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
proxy: {
'*' : {
target: 'http://localhost:' + backendPort
}
}
});
server.listen(PORT, 'localhost', function (err) {
if (err) {
return console.log(err);
}
console.log('Listening at ' + PORT);
});
}
And here is server.js:
var apiServer = require('./json-api-server');
var webpackServer = require('./webpack-server');
const PORT = process.env.PORT || 4001;
const PROD = process.env.NODE_ENV === 'production';
if (PROD) {
apiServer(PORT);
} else {
apiServer(PORT - 1);
webpackServer(PORT);
}
My filetree looks like:
--- /
----- server.js
----- webpack-server.js
----- json-api-server.js
----- src/
------- app/index.js
------- app/data/
-------------- messages.json
Both server start correctly and they don't give any errors in the terminal
I can reach localhost:4000/messages
I cannot reach localhost:4001. I got: "Can't get / "
Any helps? :)
Got it!
The * symbol here means: Use "*" to proxy all paths to the specified server.
proxy: {
'*' : {
target: 'http://localhost:' + backendPort
}
}
Which brings my index to be undefined.
So i have to point the key to the place where my json(or api) lives:
proxy: {
'/messages' : {
target: 'http://localhost:' + backendPort
}
}
As reference, this is also a valid solution:
proxy: {
'/messages': 'http://localhost:' + backendPort
}
Related
I've created a plugin in shopify using node.js & vite.js.
shopify app create node
After running using npm run dev, it generates a url like this: https://b136-0000-7400-56-bc78-5000-178b-d6f3-6000.ngrok.io/login?shop=shopname.myshopify.com
When I open this link, it start reloading infinite with error
This is my index.js:
import { resolve } from "path";
import express from "express";
import cookieParser from "cookie-parser";
import { Shopify, LATEST_API_VERSION } from "#shopify/shopify-api";
import "dotenv/config";
import applyAuthMiddleware from "./middleware/auth.js";
import verifyRequest from "./middleware/verify-request.js";
const USE_ONLINE_TOKENS = true;
const TOP_LEVEL_OAUTH_COOKIE = "shopify_top_level_oauth";
const PORT = parseInt(process.env.PORT || "8081", 10);
const isTest = process.env.NODE_ENV === "test" || !!process.env.VITE_TEST_BUILD;
Shopify.Context.initialize({
API_KEY: process.env.SHOPIFY_API_KEY,
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
SCOPES: process.env.SCOPES.split(","),
HOST_NAME: process.env.HOST.replace(/https:\/\//, ""),
API_VERSION: LATEST_API_VERSION,
IS_EMBEDDED_APP: true,
// This should be replaced with your preferred storage strategy
SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
});
// Storing the currently active shops in memory will force them to re-login when your server restarts. You should
// persist this object in your app.
const ACTIVE_SHOPIFY_SHOPS = {};
Shopify.Webhooks.Registry.addHandler("APP_UNINSTALLED", {
path: "/webhooks",
webhookHandler: async (topic, shop, body) => {
delete ACTIVE_SHOPIFY_SHOPS[shop];
},
});
// export for test use only
export async function createServer(
root = process.cwd(),
isProd = process.env.NODE_ENV === "production"
) {
const app = express();
app.set("top-level-oauth-cookie", TOP_LEVEL_OAUTH_COOKIE);
app.set("active-shopify-shops", ACTIVE_SHOPIFY_SHOPS);
app.set("use-online-tokens", USE_ONLINE_TOKENS);
app.use(cookieParser(Shopify.Context.API_SECRET_KEY));
applyAuthMiddleware(app);
app.post("/webhooks", async (req, res) => {
try {
await Shopify.Webhooks.Registry.process(req, res);
console.log(`Webhook processed, returned status code 200`);
} catch (error) {
console.log(`Failed to process webhook: ${error}`);
if (!res.headersSent) {
res.status(500).send(error.message);
}
}
});
app.get("/products-count", verifyRequest(app), async (req, res) => {
const session = await Shopify.Utils.loadCurrentSession(
req,
res,
app.get("use-online-tokens")
);
const { Product } = await import(
`#shopify/shopify-api/dist/rest-resources/${Shopify.Context.API_VERSION}/index.js`
);
const countData = await Product.count({ session });
res.status(200).send(countData);
});
app.post("/graphql", verifyRequest(app), async (req, res) => {
try {
const response = await Shopify.Utils.graphqlProxy(req, res);
res.status(200).send(response.body);
} catch (error) {
res.status(500).send(error.message);
}
});
app.use(express.json());
app.use((req, res, next) => {
const shop = req.query.shop;
if (Shopify.Context.IS_EMBEDDED_APP && shop) {
res.setHeader(
"Content-Security-Policy",
`frame-ancestors https://${shop} https://admin.shopify.com;`
);
} else {
res.setHeader("Content-Security-Policy", `frame-ancestors 'none';`);
}
next();
});
app.use("/*", (req, res, next) => {
const { shop } = req.query;
// Detect whether we need to reinstall the app, any request from Shopify will
// include a shop in the query parameters.
if (app.get("active-shopify-shops")[shop] === undefined && shop) {
res.redirect(`/auth?${new URLSearchParams(req.query).toString()}`);
} else {
next();
}
});
/**
* #type {import('vite').ViteDevServer}
*/
let vite;
if (!isProd) {
vite = await import("vite").then(({ createServer }) =>
createServer({
root,
logLevel: isTest ? "error" : "info",
server: {
port: PORT,
hmr: {
protocol: "ws",
host: "localhost",
port: 64999,
clientPort: 64999,
},
middlewareMode: "html",
},
})
);
app.use(vite.middlewares);
} else {
const compression = await import("compression").then(
({ default: fn }) => fn
);
const serveStatic = await import("serve-static").then(
({ default: fn }) => fn
);
const fs = await import("fs");
app.use(compression());
app.use(serveStatic(resolve("dist/client")));
app.use("/*", (req, res, next) => {
// Client-side routing will pick up on the correct route to render, so we always render the index here
res
.status(200)
.set("Content-Type", "text/html")
.send(fs.readFileSync(`${process.cwd()}/dist/client/index.html`));
});
}
return { app, vite };
}
if (!isTest) {
createServer().then(({ app }) => app.listen(PORT));
}
The app is installing fine but it's getting refreshed again and again due to failed connection to ws (as mentioned in the screenshot). I tried a few things around changing the settings of the HMR but doesn't seem to be connecting.
I have a simple Azure function trying to get all data from a SQL table. The connection is successful and I can connect to the database, but whenever I run the get request, I end up with an error
Exception: TypeError: connection.query is not a function
Stack: TypeError: connection.query is not a function
This is the line throwing the error
connection.query(query, (err, results, fields) => {
this is my index.js azure get function
const express = require('express')
const bodyParser = require('body-parser')
let connection = require('../configs/dbConfig')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
module.exports = async function (context, req, res) {
const query = 'SELECT * FROM entrys'
connection.query(query, (err, results, fields) => {
if (err) {
const response = { data: null, message: err.message, }
res.send(response)
}
const pokemons = [...results]
const response = {
data: pokemons,
message: 'All entrys successfully retrieved.',
}
res.send(response)
})
}
Am using tedious as the connection driver. my dbconfig
let Connection = require('tedious').Connection;
let pool = {
server: "localhost", // or "localhost"
authentication: {
type: "default",
options: {
userName: "sa",
password: "root",
}
},
options: {
database: "testing",
encrypt: false
}
};
var connection = new Connection(pool);
connection.on('connect',function(err){
if(err){
console.log('Connection Failed');
throw err;
}
else{
console.log('Connected');
}
});
module.exports = connection
what am I doing wrong, thank you in advance
You should use Request to query.
In the official documentation, I did not see the usage of connection.query. It is not recommended that you use tedious when you are not very familiar with it. I have a sample code here, I hope it helps you.
You can download my Sample Code which use mssql package.
var express = require('express');
var router = express.Router();
let connection = require('../configs/dbConfig')
var Request = require('tedious').Request;
/* GET users listing. */
router.get('/', function(req, res, next) {
request = new Request("select 42, 'hello world'", function(err, rowCount) {
if (err) {
console.log(err);
} else {
console.log(rowCount + ' rows');
}
});
request.on('row', function(columns) {
columns.forEach(function(column) {
console.log(column.value);
});
});
connection.execSql(request);
res.send('respond with a resource');
});
module.exports = router;
Test Result:
I'm build vue app, and for mine app need api request to server from client, also necessary proxy any request.
It's mine vue.config.js
const producer = require('./src/kafka/producer');
const bodyParser = require('body-parser')
module.exports = {
devServer: {
setup: function (app, server) {
app.use(bodyParser.json())
app.post('/send-message', function (req, res) {
producer.send(req.body)
.then(() => {
res.json({result: true, error: null});
})
.catch((e) => {
res.status(500).json({result: false, error: e});
})
});
},
proxy: {
'/v2/order/by-number': {
target: 'http://address-here'
}
}
}
};
As you can see so i'm use body-parser app.use(bodyParser.json())
After I added it, proxying stopped working for me. Request to /send-message freezes after show me error
Proxy error: Could not proxy request path-here from localhost:8080
to http://address-here
Internet searches have not led to a solution.
For a long time, i find a solution:
Add second param jsonParser to app.post()
See full example
const producer = require('./src/kafka/producer');
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json({limit: '1mb'});
module.exports = {
devServer: {
setup: function (app, server) {
app.post('/send-message', jsonParser, function (req, res) {
producer.send(req.body)
.then(() => {
res.json({result: true, error: null});
})
.catch((e) => {
res.status(500).json({result: false, error: e});
})
});
},
proxy: {
'path': {
target: 'http://address-here'
}
}
}
};
Hey i am and i am making an api here is the source code
//Initiallising node modules
var express = require("express");
var bodyParser = require("body-parser");
var sql = require("mssql");
var app = express();
// Body Parser Middleware
app.use(bodyParser.json());
//CORS Middleware
app.use(function (req, res, next) {
//Enabling CORS
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
next();
});
//Setting up server
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
//Initiallising connection string
var dbConfig = {
user: 'sa',
password: '*****',
server: '94.200.123.222,1433',
database: 'CUBES_HO',
};
//Function to connect to database and execute query
var executeQuery = function(res, query){
sql.connect(dbConfig, function (err) {
if (err) {
console.log("Error while connecting database :- " + err);
res.send(err);
}
else {
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function (err, res) {
if (err) {
console.log("Error while querying database :- " + err);
res.send(err);
sql.close();
}
else {
res.send(res);
}
sql.close();
});
}
});
}
//GET API
app.get("/api/user", function(req , res){
var query = "select * from [osama] where bill_hdr_key = '31'";
executeQuery (res, query);
});
and the problem is that when ever i excecute this it gives me error
Failed to lookup instance on 94.200.123.222,1433 - getaddrinfo ENOTFOUND 94.200.123.222,1433",
the server is up and running and can be access through SSMS . Help Me Kindly
With the respect of your code I have tried to resolve your issue with following code, there are few mistakes you did so I have rectified it here.
const express = require("express");
const bodyParser = require("body-parser");
const sql = require("mssql");
const app = express();
const port = 3131;
// Body Parser Middleware
app.use(bodyParser.json());
//CORS Middleware
app.use(function (req, res, next) {
//Enabling CORS
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
next();
});
//Initiallising connection string
var dbConfig = {
user: 'sa',
password: "******",
server: '94.200.123.222',
database: 'CUBES_HO',
};
function executeQuery(query) {
return new Promise((resolve, reject) => {
sql.connect(dbConfig, function (err) {
if (err) {
reject(err);
sql.close();
} else {
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query(query, function (err, data) {
if (err) {
reject(err);
sql.close();
} else {
resolve(data);
sql.close();
}
});
}
});
});
}
//GET API
app.get("/", function (req, res) {
var query = "select * from [osama] where bill_hdr_key = '31'";
executeQuery(query)
.then((data) => {
res.status(200).send({ "msg": "Records fetched", "data": data.recordsets });
}).catch((err) => {
res.status(500).json({ "msg": err.message });
});
});
//Setting up server
var server = app.listen(port || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
Hope, it may help to resolve your bug.
I'm trying to develop a small API using express. Just want to have 2 views, which, in my case, means 2 html files. One accesing as default with "/" and the other with "/lessons", so we got 2 get controls plus another one which handles every other get input.
*Both files are in the "views" folder and their extension is: *.html
I have no problem accessing the "app.get("/lessons", function..." in fact I know I can acces to that because a simple "console.log(..)" command. The problem is that I got the next error when trying to render:
[TypeError: this.engine is not a function].
Could you help me? I can't understand where is the problem or what I'm doing wrong. I believe it's in the rendering function and has something to do with its configuration and the lessons.html file because index.html has no problem using the same approach.
var express = require('express');
var app = express();
var mod = require('./module');
app.use(express.static('public'));
app.use(express.static('views'));
var port = process.env.PORT || 8080;
app.listen(port, function() {
console.log('Node.js listening on port ' + port);
});
app.get("/", function(req, res) {
console.log("Passed through /");
res.render('index.html');
});
app.get("/lessons", function(req, res) {
console.log("passed through lessons");
res.render('lessons.html', function(err, html) {
if(err) {
console.log(err);
}
res.send(html);
});
//I have tried to to use just: res.render('lessons.html');
});
app.get("*", function(req, res) {
var usageReq = false;
var urlPassed = req.url;
urlPassed = urlPassed.substring(1, urlPassed.length); //remove first "/"
var expected = mod.seeIfExpected(urlPassed); //returns url(if url) or num(if number) or na(if it doesn't match any)
mod.processInfo(expected, urlPassed, function(answer) {
if (answer.found == false && answer.jsonRes == true && answer.info != "inserted") {
res.json({
"error": answer.info
});
} else {
if (answer.jsonRes == true) {
res.json({
"long_url": answer.url,
"short_url": answer.id
});
} else { // go to url
var newUrl = "https://" + answer.url;
res.redirect(newUrl);
}
}
});
});