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?

1 Like

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();
  }
});
13 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

I’m using default meteor package “webapp” to bind API links and this package: simple:json-routes to serialize body data. Here is the link.

And this code snippet to access it:

WebApp.connectHandlers.use('/api/request', (req, res, next) => {
    console.log(req.body);
});
1 Like