Is there a way to receive requests (get or post) on Meteor server?

Meteor 1.6.1

Let’s say I have a Meteor server running on a computer. If I had another computer trying to send a request to the server, I would do something like http://meteor.server.local/some-action?id=xyz&data=123

a computer -> (get or post) -> the Meteor server

Is there a way to receive requests on the server side?

My personal go to for this is meteorhacks:picker

3 Likes

Thanks, I can receive data now like below.

// server/main.js

import { Meteor } from "meteor/meteor"
import bodyParser from "body-parser"
// extended: true uses qs to have params in JSON format
// better when params are nested
Picker.middleware(bodyParser.urlencoded({ extended: true }))

Meteor.startup(() => {
  Picker.route("/hello", function(params, req, res, next) {
    console.log(params)   // some-action?a=123& ...  query params
    console.log(req.body)  // posted data
    res.end()
  })
})

Quick word of warning about the original Picker package - it hasn’t been updated in quite some time, and is incompatible with some of the recent Meteor core WebApp changes. For example, it breaks dynamic imports. You might be better off finding a more up to date fork of Picker, or skipping Picker completely, and just integrating with Meteor’s connect middleware layer directly. Meteor makes this quite easy:

/server/index.js

import { WebApp } from 'meteor/webapp';

WebApp.connectHandlers.use((req, res, next) => {
  if (req.url === '/hello') {
    console.log(req);
    res.end()
  } else {
    next();
  }
});
10 Likes

Thank you for the follow-up. I updated my code, and this is working for me.

import { WebApp } from "meteor/webapp"
import bodyParser from "body-parser"

WebApp.connectHandlers.use(bodyParser.urlencoded({ extended: true }))
WebApp.connectHandlers.use((req, res, next) => {
  if (req.url.startsWith("/hello")) {
    console.log(req.query)
    console.log(req.body)
    res.statusCode = 200
    res.end()
  } else {
    next()
  }
})


or this is even better?

import { WebApp } from "meteor/webapp"
import bodyParser from "body-parser"
import router from "router"
const endpoint = router()

endpoint.post("/hello", (req, res) => {
  console.log(req.query)
  console.log(req.body)
  res.writeHead(200)
  res.end()
})

WebApp.connectHandlers.use(bodyParser.urlencoded({ extended: true }))
WebApp.connectHandlers.use(endpoint)

Both approaches work well. Using router will save you from some additional boilerplate, but you’ll be adding in another dependency. Always a trade-off, and there isn’t really a single right answer - they’ll both get the job done.

Hi there, I’ve tried pigel approach on my recently updated app without success when using mailgun routes for incoming messages (store and notify). I used to go with Picker to get the notification of a new message from mailgun, but then I had the already reported error. Then I tried a fresh meteor create app, pasted the suggested code in sever/main (tried with both versions), added the npm dependencies (body-parser and router) and both console.logs show an empty object, ie req.query = {} and req.body = {}. Tested using the “Send Sample POST” in the routes section of Mailgun’s dashboard. I get the request object (console.log(req) yields a bunch of stuff) but without the body key
Any suggestion would be really appreciated

Sorry for the confusion guys. I guess that Mailgun’s “send Sample POST” doesn’t send a body and just cheks if a 200 code is returned. The fact is that testing with a real reply message does work, but only using the route approach. The other method still returns an empty body