(Note: I'm using javascript, not typescript in my Functions)
My Firebase Project has a single 'oauth' function, which has a series of endpoints created through express app/routers.
I don't understand how to run the functions at these endpoints from the Cloud Functions Shell to debug them locally.
Here is my index.js
const twitter = require("./oauth/twitter");
const app = express();
app.use("/signin/twitter", twitter.router);
exports.oauth = functions.https.onRequest(app);
My actual endpoints are in a twitter.js file (and others for other providers)
router.get("/authorize", (req, res) => {...});
router.get("/authorize_callback", (req, res) => {...});
router.get("/deauthorize", (req, res) => {...});
If I run 'firebase functions:shell' in my terminal, it only shows the 'oauth' function.
I would like to access a function such as 'oauth/signin/twitter/authorize' just like I do in the browser after deploying, but I have no idea how to!
Is this possible?
I believe this is the documentation you are looking for. Essentially, you can invoke those express-like routes by calling the method (get, post, etc.) within the Cloud Function in the shell like such: functionName.get('/test')
Related
There is a solution to this error without the use of Firebase here when using app.listen(8080) however this does not work while serving in cloud functions with exports.app = functions.https.onRequest(app)
Here is a simple reproduction code
const app = express();
app.get('**', (req, res) => res.send('working'));
app.use((err, req, res, next) => res.redirect('/404'));
exports.app = functions.https.onRequest(app) // doesnt work
// app.listen(5000) // works
How do you go about catching this error in firebase functions? I would like the redirect to work.
firebase test: firebase serve --only functions
express serve: node index.js
URL to test: http://localhost:5000/%CO
Note that the additional %CO is the one that cannot be decoded by express. This error is caught while serving with the express method but not with the firebase functions method.
As this seems like a bug, I have also created an issue here on github incase I find no workaround on it.
Try changing the name of app in exports.
exports.newApp = functions.https.onRequest(app)
According to the documentation, the correct way of using an Express app with Firebase Functions is to pass the application to a Function like:
// Expose Express API as a single Cloud Function:
exports.app = functions.https.onRequest(app);
Listening to a port for requests does not apply when running through Firebase Functions. As for how to catch errors when passing your app to a function, it’s done in the same way as the question you referenced as far as I have reviewed. You can catch errors by using Express middleware while using Cloud Functions.
Moreover, implementing redirects with Firebase Functions is explained in this related question, which makes use of the documentation to configure how to redirect by modifying the firebase.json file.
I'm working on a vuejs/express fullstack web app, and I know you can specify endpoints on the server like:
app.get('/', function (req, res) {
res.send('GET request to the homepage')
})
Which you can then hit from the client to display the home page.
But I'm wondering what about when you don't need to go to a 'route'? For example, you just want to send some data from client to server to do some calculations and then send data back to the client - do you still specify an endpoint e.g /FunctionName and access it from the frontend in the same way or is there some other way to call a function in the backend?
This is the 'express' way to define endpoints (or routes), regardless if it will return an html page like the example you've specified, or do some computation by calling other functions with user-specified parameters.
As a basic example:
app.post('/myendpoint', function (req, res) {
returnValues = callMyFunction(req)
res.send(returnValues)
})
I'm challenged with the task to explore node.js as an alternative to ASP.NET Web API in providing a RESTful API.
I've been developing ASP.NET Web API for some time now and have got used to having certain things within that framework, I'm wondering what others are doing down the node.js route for some of these things: -
What ORM to use against MS SQL instead of Entity Framework
Is there a nice way of handling the routing similarly to what you get in Web API with the route template (routeTemplate: "api/{controller}/{id}")
I'm using Express so far and haven't found a way of applying something like this at a 'top level' so that I can have separate controllers...
That's it so far, I'm sure there are many, many more questions to come but those are my immediate concerns if anybody can help with these?
For ORM the 2 most libraries used are knexjs and sequelize, however, I prefer knex.
For the mapping part, as far as I know, there isn't a way to do it like in the c#. Usually what I do is, in the app.js load a file with my routes index. Here is an example,
In your app.js
app.use('/', require('./backend/routes/index'))
Then, in your routes/index
import express from 'express'
const router = express.Router()
// GET /
router.get('/', function (req, res) {
})
// GET /countries
router.get('/countries', (req, res, next) => {
})
// POST /subscribe
router.post('/subscribe', checkAuth, generalBodyValidation, (req, res, next) => {
})
// All routes to /admin are being solved in the backend/routes/admin/index file
router.use('/admin', require('./backend/routes/admin/index'))
module.exports = router
Your admin/index file can be
import express from 'express'
const router = express.Router()
// POST /admin/login
router.post('/login', (req, res, next) => {
})
module.exports = router
With this, you will be able to have a better structure for your routes.
Hope this asks your questions, if it does mark my answer as correct, if not tell me what you didn't understand :D
How can I add common methods/functions that can be used by different routes built using express in nodejs?
I created a nodejs server that is currently serving 3 APIs. For example:
/cars
/cars/:id
/cars/:id/sellers
All these 3 APIs retrieves data from another external APIs. So, I already have some code that is similar in all of those routes. For example, sending a GET request to the external API endpoint but with different parameters.
For the last API in my list above, I want to enhance it so that it will take optional paramters (lastname, firstname). I could have another API endpoint like this:
/cars/:id/sellers/:lastname&:firstname
But in this case the logic for this and the 3rd API in my list will be almost identical.
I'd like to create some util functions that I can call from any of my API routes with different parameters. I'm not quite sure to do this or where to begin.
Any suggestions?
app.use((req, res, next) => {
//req.someParam
//your logic
next();
});
You can use a middleware like this make sure to add it after your routes has defined, it will work as a common middleware in the routes
router.post('/cars', (req, res, next) => {
// if() some condition
req.someParam = "param";
next();
});
Looking for a good example of how to implement a node API gateway for a microservice application, I understand the purpose of having a gateway, I am just not sure of how to implement this without just adding another level of RESTful route calls. To me a gateway is supposed to just direct the route to the microservice.
API Gateway port 3000
router.use('/microservicename/*', function (req, res, next) {
**code that will direct to microservice**
});
Microservice1 server.js port 3001
var express = require('express');
var app = express();
var routes = require('./routes/routes');
app.use('/microservicename', routes);
var server = app.listen(3001, function () {
console.log('Server running at http://127.0.0.1:3001/');
});
Microservice1 router.js (3001)
router.get('/route1', function (req, res, next) {
//get route code
});
router.post('/route2', function (req, res, next) {
//post route code
});
router.put('/route3', function (req, res, next) {
//put route code
});
router.delete('/route4', function (req, res, next) {
//delete route code
});
Assuming your microservice is its own http server (if not, then please explain more about its architecture) and assuming your API is designed such that you can easily identify which routes go to which microservice without specifying every single possible route, then you should be able to create one route handler for an entire microservice (or at worst a very small number of route handlers for the entire microservice).
For example, if all requests that start with /api/foo go to the foo microservice, then you should be able to have a single route handler that catches /api/foo/* and proxies that to the microservice. If you have common middleware for all requests (such as middleware that runs or verifies an authentication process), that can be in the stack before the proxy route handlers so it will be invoked for all requests that go to the microservice.
If you don't have a 1-to-1 mapping between incoming API calls and microservice APIs, then you have to create a mapping between the two. Depending upon the level of mismatch, you may be able to do this with a table-driven approach where you specify what matches with what in a table and then one piece of generic code processes all the definitions in the table.