node.js: How to look up an API? - javascript

I am a new practicer of Node.js. I have a pretty silly problem. When I use packages or some code written by other people, I cannot find out where the definitions of components. Right now, I am struggling for searching for request.files used in Express.js. My questions are, if I don't study the source:
Where should I go to see the formal API document on request.files?
How should I identify the type of a req object: http.request or expressjs.request?
What are optimal ways to find an API's definition?

Express has pretty good documentation. Take a look at what the request object has by default. This of course can be modified by middleware. In this case, you're looking for req.files, which could be added by a few different middleware. A Google search for express req.files shows expressjs/multer as the fourth result. Taking a look at that we see:
var express = require('express')
var multer = require('multer')
var app = express()
app.use(multer({ dest: './uploads/'}))
You can access the fields and files in the request object:
console.log(req.body)
console.log(req.files)
So in this case, the multer middleware will add the ability to handle uploaded files, and make those files available at req.files.

Related

How to access underlying express app in Keystone 6?

I'm using Keystone 6 for my backend and I'm trying to integrate Stripe, which requires access to the underlying express app to pass a client secret to the client from the server. This is highlighted in the Stripe documentation here: https://stripe.com/docs/payments/payment-intents#passing-to-client
I'm having trouble figuring out how to access the express app in Keystone 6 though and they don't seem to mention anything about this in the documentation. Any help would be appreciated.
The short answer is Keystone 6 doesn't support this yet.
The longer answer has two parts:
This functionality is coming
We've been discussing this requirement internally and the priority of it has been raised. We're updating the public roadmap to reflect this next week.
The functionality itself should arrive soon after. (Unfortunately I can't commit to a release date.)
Getting access to the Express app is possible, it's just a real pain right now
If you look at Keystone's start command you can see where it
calls createExpressServer().
This just returns an express app with the GraphQL API and a few other bits and bobs.
But there's actually nothing forcing you to use the build in keystone start command – You can copy this code, hack it up and just run it directly yourself.
Eg. you could replace this...
const server = await createExpressServer(
config,
graphQLSchema,
keystone.createContext,
false,
getAdminPath(cwd)
);
With...
const server = express();
server.get('/hello-world', (req, res) => {
res.send('Hello');
});
const keystoneServer = await createExpressServer(
config,
graphQLSchema,
keystone.createContext,
false,
getAdminPath(cwd)
);
server.use(keystoneServer);
And your /hello-world endpoint should take precedence over the stuff Keystone adds.
Unfortunately, this doesn't work for the dev command so, in your local environment you'll need to do it differently.
One option is to start a second express server that you control and put it on a different port and include your custom routes there.
You can still do this from within your Keystone app codebase but having different URLs in different environments can be annoying.
You'll probably need an environment variable just for your custom endpoints URL, with values like this in production:
# Production
GRAPHQL_ENDPOINT="https://api.example.com/api/graphql"
CUSTOM_ENDPOINT="https://api.example.com/hello-world"
And this in dev:
# Dev
GRAPHQL_ENDPOINT="http://localhost:3000/api/graphql"
CUSTOM_ENDPOINT="http://localhost:3100/hello-world"
It's ugly but it does work.
I'll update this answer when the "official" functionality lands.

Is there any purpose of splitting up express and app?

I see these two lines in ( every ?) Express app.
const express = require('express');
const app = express();
I have to wonder if any parameters can be passed to express()?
Checked here and did not see any
https://expressjs.com/en/4x/api.html
Why are some methods on express() and some on app()?
It seems like they should be combined and have all methods on one object.
express does not take any parameters, no. The purpose of calling it is to create the app object, so the fact you have to call it does make sense, even without parameters.
Another way you often see that written is:
const app = require("express")();
It'll need to be separate again when using ESM, though.
import express from "express"; // Or similar
const app = express();
In a comment you've said:
For example, is there anything useful I can do with out creating app? Is there anything I can do only with express?
As far as I know, you have to have create at least one Application object to do anything useful with Express. Note that you don't have to create just one app. That's the typical use case, but there's no reason you can't create multiple apps running on different ports.
You may be wondering why express can't just give you an Application object directly from require. The reason is that modules are only loaded once and cached, so what you get from require is shared. So Express exports the express function, which you use to create the Application object (or objects, plural, if you want more than one).
Is there anything I can do only with express?
The reason for doing two separate lines like this:
const express = require('express');
const app = express();
instead of this:
const app = require('express')();
is that the express module has other methods on it that are sometimes needed such as:
express.static(...) // middleware for serving static files
express.json(...) // middleware for parsing json requests
express.urlencoded(...) // middleware for parsing urlencoded requests
express.Router(...) // constructor for a new Router object

Express.js - Helmet.js and other middleware, and mounted applications?

In a recent learning project, I'm using three Express.js applications to separate the project into more manageable pieces.
One application is the "primary" app, the one that listens for connections. The other two are mounted at specific routes on the primary app.
Is it sufficient to call app.disable('x-powered-by'); on the primary app to disable the X-Powered-By header, or would this need to be done in each of the mounted apps as well?
Similarly, I'm looking into using Helmet.js to try and add a bit of additional security to the entire project. Is it enough to include any middleware from Helmet.js on the primary app, or would these also need to be defined in the mounted apps?
I don't feel as though I understand how some settings and middleware affect mounted Express.js apps, and would appreciate further explanation from anyone with more experience.
Edit: After playing with app.disable('x-powered-by') and examining responses from the server, the X-Powered-By header appears if I don't disable it in both the primary application instance and any mounted application instances. I therefore presume Helmet.js middleware operate the same way, but I'm not 100% certain. Can anyone confirm if this is the expected behavior?
You're right about everything you've said.
It sounds like you're doing something like this:
var express = require('express')
var mainApp = express()
var miniAppA = express()
var miniAppB = express()
mainApp.use('/a', miniAppA)
mainApp.use('/b', miniAppB)
mainApp.listen(3000)
This is an okay way to do things, but headers will be overridden in the sub-apps, as you saw.
You can use Express 4's routers feature to mitigate this. Instead of making new mini-apps with express(), you can use express.Router(). These are Express apps with fewer features (for example, they don't set headers the same way).
Something like this might solve your issue:
var express = require('express')
var mainApp = express()
var miniAppA = express.Router()
var miniAppB = express.Router()
mainApp.use('/a', miniAppA)
mainApp.use('/b', miniAppB)
mainApp.listen(3000)

Communication between an express node server and its displaying html

Really fast, this question may have already been asked, but I am not totally clear on the terminology and have had no success when searching for a solution.
I am attempting to create a simple web application that can receive get and post requests. Then, I would like to take the information I receive from these requests and use them in a javascript file embedded in html that is displayed. I think it may be more clear with code. This is my app.js:
var express = require('express');
var app = express();
var assert = require('assert');
app.use(express.static('javascript'));
app.get('/', function(req, res) {
res.render('index.jade');
});
app.listen(3000);
I would then like to be able to take information received from a get or post request, specifically in JSON format, and then be able to use it in javascript that I have linked to index.jade. To make matters slightly more confusing in index.jade the only line is:
include map.html
So ideally I would be able to get the information to javascript in that html file.
I want to be able to pretty continuously update map.html using javascript based on frequent get and post commands.
This could be a very simple solution, I am pretty new with web application programming in general, and I have been struggling with this problem. Thanks in advance, and ask if you need any clarification.
I think you need to understand what you are doing. You are creating a web server using node.js. Express framework simplifies that for you. The official documentation of express is pretty great. You should refer that especially this link.
Now, in your application, you need to create endpoints for GET and POST requests. You have already created one endpoint "/" (root location) that loads your home page which is the contents of the file index.jade. A small example is :
app.get('/json', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ a: 1 }));
});
Jade is a templating engine which resolves to HTML. You should refer its documentation as well. Since as you said, you are not very familiar with these, you could simply use HTML as well.
After this tasks are quite simple. In your javascript, using ajax calls you can access the GET or POST endpoints of your server and do the desired actions.
Hope it helps!
The way I get it you want to be able to call an endpoint (lets assume /awesome) pass some info and then write to a Javascript file that you can then reference in your html.
Something like the below would write a main.js file in your public folder. You can make it write whatever you want.
var fs = require('fs');
fs.writeFile("/public/main.js", "console.log('Hello!')", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
You can then reference /public/main.js in your html.
Check that: Writing files in Node.js
If I misunderstood your intentions, apologies. :)
So you want to reviece continuously data from the server maybe web sockts are an option for you http://socket.io/docs/
This way u will open a stable connection from the client to the server. This is a great way if u want to get updates done by other clients.
If you want to trigger the changes by the client then ajaxs calls(http://www.w3schools.com/ajax/) as hkasera mentioned are the way to go.

Send URL string to other script with Node.js

I am starting to learn Node.js, using Express with Jade and Mongoose as my default toolbox. I used to develop in PHP, migrated to Python, and learned MVC through Django. Having a large client-side JS game and some inspiration from Mozilla.org, I am willing to make a multiplayer game -- and saw this as a noncommercial opportunity to learn Node: I can take my time with it.
However, I ran into a problem. I'm not trying to write an MVC system on my own, just to separate my site's "apps" like most MVCs do. The question is probably basic -- having this chunk of code:
app.get(/^blog/, function(req, res) {
require("./blog")();
});
... I understand the basics of Node/Express' URL masking, however I need to pass the rest of the URL string (everything that's after mysite.com/blog) to another URL parsing script, inside the blogapp.
I googled around for a while and couldn't find a good solution. I even found a full tutorial on building an MVC scheme in Node and Express written for an older Express version, but that's a bit over the top for now. Can you provide me a simple solution?
I think blog/index.js should look something like this:
module.exports = function(urlstring) {
if(urlstring.indexOf('post') != -1) {
// do stuff...
}
else if(urlstring === '/') {
// return home.jade or something
}
};
I hope I'm being clear. Thanks in advance!
With express there is no need to parse your URLs on your own. I guess you'll want to build your blog URLs somehow like this
/blog Show a list of blog posts
/blog/post/1 Show blog post with id '1'
With express 4 you can set up a router for your blog path or a mounted app. Mounted apps allow you to let an app handle all sub URLs of a base URL path. See the express documentation for more detail.
I'd like to demonstrate how you can use the express 4 router together with the mounting feature of express to build blog routes.
// Set up express app
var app = express();
// Set up a router
var router = express.Router();
router.get('/', function(req, res) {
// Show a list of blog posts
}
router.get('/post/:id', function(req, res) {
// Show a single blog post
}
// Mount router
app.use('/blog', router);
A benefit of this solution is that your routes registered in the router always get relative URLs with out the /blog prefix so you may reuse your blog routes in some other project under a URL like /companyblog.

Categories

Resources