How to set options for json-server as a module? - json-server

Suppose we have the following command line to run a json-server (https://github.com/typicode/json-server):
json-server db.json --routes routes.json --port 8008 --delay 1000
If we were to run json-server as a module, how do we set these options? I can see the db.json defined and the port defined. But it is not clear how the rest of the options can be defined.
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middleWares = jsonServer.defaults();
server.use(middleWares);
router.render = (req, res) => {
console.log(req);
};
server.use(router);
server.listen(8008, () => {
console.log('JSON Server is running');
});

I found how to set the delay. This requires installing the connect-pause package, which is also used in the json-server code (https://www.npmjs.com/package/connect-pause):
npm install connect-pause
Then on the server.js file, I added the following a require('connect-pause') and used it in the json server app. Here is my code:
const fs = require('fs');
const pause = require('connect-pause');
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();
server.use(middlewares);
server.use(jsonServer.bodyParser);
//
// Define custom routes (routes.json)
//
var routes = JSON.parse(fs.readFileSync('routes.json'));
server.use(jsonServer.rewriter(routes));
...
server.use(pause(1000));
server.use(router);
server.listen(8008, () => {
console.log('JSON Server is running');
});
To set any other option varies wildly, but I mainly needed to know how to set the delay.

Related

Minimal Sveltekit + pg integration fails with "status" error

I'm trying to get Postgres working with sveltekit and a very minimal example is giving me issues. This is probably a configuration thing but the error I'm getting back from sveltekit makes no sense to me.
I start by installing a new project:
npm create svelte#latest my-testapp
Then I install "pg" to get Postgres pooling:
npm i pg
Then I add a page under src/lib/db.js:
import { Client, Pool } from 'pg';
const pool = new Pool({
user: 'xxx',
host: 'xxx',
database: 'xxx',
password: 'xxx',
port: 5432,
})
export const connectToDB = async () => await pool.connect();
Finally I add src/hooks.server.js to give me access to the pool within routes:
import { connectToDB } from '$lib/db';
export const handle = async ({event, resolve}) => {
const dbconn = await connectToDB();
event.locals = { dbconn };
const response = await resolve(event);
dbconn.release();
}
The server fails to compile with a couple of these errors:
Cannot read properties of undefined (reading 'status')
TypeError: Cannot read properties of undefined (reading 'status')
at respond (file:///C:/Users/user/code/svelte/my-testapp/node_modules/#sveltejs/kit/src/runtime/server/index.js:314:16)
at async file:///C:/Users/user/code/svelte/my-testapp/node_modules/#sveltejs/kit/src/exports/vite/dev/index.js:406:22
Not sure where "status" is coming from, seems to be part of the initial scaffolding. Any help appreciated.
Also - if there is a more straightforward way to integrate pg with sveltekit then I'm happy to hear about it. Thanks
My bad - the hooks function wasn't returning the response.
Hooks.server.js should read:
import { connectToDB } from '$lib/db';
export const handle = async ({event, resolve}) => {
const dbconn = await connectToDB();
event.locals = { dbconn };
const response = await resolve(event);
dbconn.release();
return response
}

How to add express-winston to Parse Server example?

How do I use express-winston to log all http requests sent to Parse Server?
I tried this:
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
const app = express();
const winston = require('winston')
const expressWinston = require('express-winston');
app.use(expressWinston.logger({
transports: [
new winston.transports.Console()
],
format: winston.format.combine(
winston.format.colorize(),
winston.format.json()
)
}));
app.use('/parse', new ParseServer({
// ...
}));
const httpServer = require('http').createServer(app);
httpServer.listen(1337);
But there is no log output in the console from express-winston.
What's missing here?
Logging actually worked, but the output was not displayed to the debug console.
I was debugging in Visual Studio Code and had to set "outputCapture": "std" in the launch configuration to see the logs as described in the launch attributes.

GET request to port 81 using axios (or even js native fetch)

I have a Node.js API running on port 81, and want to hit the endpoint from JavaScript like this:
function fetchFromApi() {
const axios = require('axios');
console.log('using port 81',axios.defaults);
axios.request({
method: 'get',
url:'/api/getAccountList',
port: 81, // port options is not valid - this does not have the desired result
})
.then( response => {
console.log(response);
const data = response.data;
const errors = (data.errors) ? data.errors : false;
if (errors) {
setErrors(errors);
}
})
.catch( reason => {
console.log(reason);
});
}
The network tab in chrome developer tools show this request still went to port 80.
When I try to code the entire protocol, port, host and url in the axios request, I get a CORS error:
axios.get('http://localhost:81/api/getAccountList')
Error is:
Access to XMLHttpRequest at 'http://localhost:81/api/getAccountList'
from origin 'http://localhost' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
My API server is a simple Node.js server:
const express = require('express');
const app = express();
const port = 81;
app.get('/api/getAccountList', (req, res) => {
const userIdBy = req.params.userIdBy;
const apiToken = req.params.apiToken;
if (!(userIdBy && apiToken)) {
res.status(200).json({errors:['Missing credentials']});
return true;
}
// check the user id and api token match up:
console.log('Hello');
});
app.listen(port);
How can I make my client query the API using HTTP on port 81?
CORS is a security feature in most browsers that disables cross-origin requests—i.e., requests from a different hostname. To surpass it, install the cors dependency on your Express server via npm using:
npm install cors
Then you need to add it to every app via the cors() function to every {{httpMethod}} you want to allow other domains to make requests to.
Try editing your code like this:
const express = require('express');
const cors = require('cors')
const app = express();
const port = 81;
app.get('/api/getAccountList', cors(), (req, res)=>{})
On the client side, to get Axios to GET from port 81 on the same host as the javascript is running I used:
import axios from 'axios';
//...
//...
axios.defaults.baseURL = window.location.protocol + "//" + window.location.hostname + ":81";
const result = await axios('/your/endpoint');
//...
//...
Can you try to add this to your Node.js server?
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:81');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
You can try to add only Access-Control-Allow-Origin header or modify others to your needs.
To achieve the required CORS protection AND avoid hard coding the servers FQDN / hostname, I used this code in my node api server:
const express = require('express');
const app = express();
const apiProviderPort = 81;
const allowedApiConsumerPort = 80;
app.use(function (req, res, next) {
const host = req.get('host'); // NOTE host is the fqdn:port
const hostSplit = host.split(':');
var fqdn;
if (hostSplit.length == 1) {
// I am not sure this is needed, it will be if hostname is fqdn[:port]
fqdn = host;
} else if (hostSplit.length == 2) {
fqdn = hostSplit[0];
} else {
console.log('Error the host contained multiple colons!');
}
console.log('protocol:',req.protocol,'host:',host,'fqdn:' + fqdn);
// next line edited March 2020 - I changed + '//' + to + '//:' +
// as the developer tools console showed
// The 'Access-Control-Allow-Origin' header contains the invalid value 'http//localhost:3000'.
const allowableOrigin = req.protocol + '//' + fqdn + ':' + allowedApiConsumerPort;
console.log('allowableOrigin:',allowableOrigin)
res.setHeader('Access-Control-Allow-Origin', allowableOrigin);
next();
});
app.get('/api/userDocReportData/', (req, res) => {
const userIdBy = req.params.userIdBy;
const apiToken = req.params.apiToken;
if (!(userIdBy && apiToken)) {
res.status(200).json({errors:['Missing credentials']});
return true;
}
// check the user id and api token match up:
// ...
// get your payload etc
res.status(200).json({errors:false,payload:{} });
});
app.listen(apiProviderPort);
I enhanced #webprogrammers answer above as I wanted code that could work in any environment (localhost; test.example.com, live.example.com etc)

Why does node server.js work, but node ./backend/server.js give me this error?

I currently have the following file directories:
and if i do node server.js while in the backend directory, the server runs. However, if I am in the root directory, and do node ./backend/server.js, the following error shows up:
Here is my code for the mongodb server on server.js:
const express = require('express');
const mongoose = require('mongoose');
const dotenv = require('dotenv')
dotenv.config();
const app = express();
app.use(cors({origin: true,credentials: true}));
app.use(express.json());
const PORT = process.env.port || 5000;
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, { useNewUrlParser: true, useCreateIndex: true });
const connection = mongoose.connection
connection.once('open', () => {
console.log("MongoDB database connection established successfully");
})
I believe, it is because your .env file is not in the root.
Explanation:
When you run node server.js you application looks for .env file and load environment variables. But, when you navigate to root and run node ./backend/server.js it can't find .env file. So process.env.ATLAS_URI is undefined.

Write EPIPE error when filling form using node-pdftk

I am trying to fill a pdf form using nodejs.
Im trying to use node-pdftk package for the same.Did following steps:
Installed pdftk for windows
mapped the path to the environment variables PATH
installed node-pdf package
`const express = require('express')
const app = express()
const cors = require('cors')
const pdftk = require('node-pdftk');
const bodyParser = require('body-parser');
var multer = require('multer'); // v1.0.5
var upload = multer();
app.listen(8000, () => {
console.log('Server started!')
});
var pdfPath='OoPdfFormExample.pdf';
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
var formdata = {
'Given Name': 'Swetha',
'Family Name': 'Gulapannavar'
}
app.post('/api/file', upload.array(), (req, res, next) => {
//var buffer=JSON.stringify(Buffer.from(req.body));
var buffer=Buffer.from(req.body)
pdftk
.input(pdfPath)
.fillForm(formdata)
.flatten()
.output()
.then(buffer => {
// Still returns a buffer
res.type('application/pdf'); // If you omit this line, file will
download
res.send(buf);
})
.catch(err => {
res.send(err.message)
// handle errors
});
});`
but i'm getting following error when i try to execute the same.
Write EPIPE error.
This could be caused by node-pdftk not being able to find the PDFtk binaries; your PATH variable may not be set correctly for the account running your web service. You can set the bin path directly inside of your application using node-pdftk's configure function, which is briefly described on the node-pdftk npm project page. If that doesn't work, try configuring the tempDir path.