Skip to content

Instantly share code, notes, and snippets.

@matfin
Last active January 5, 2018 14:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matfin/14f50d035c01ce333332 to your computer and use it in GitHub Desktop.
Save matfin/14f50d035c01ce333332 to your computer and use it in GitHub Desktop.
Dealing with custom Content-Types and POST requests in node.js and Meteor

This describes how to deal with custom content types and hooks in a Meteor JS based webapp which pulls its content from Contentful.

My goal was to reload content into a Meteor server side collection and have it update any time a user on Contentful.com updated content there. Contentful provide a very helpful hook mechanism, whereby a POST request is made to an endpoint of your choosing when content has been updated.

I was using the server side component of IronRouter to listen for incoming POST requests from Contentful and when they arrived, the request body was empty. This is because Contentful have a custom content type 'application/vnd.contentful.management.v1+json' and IronRouter does not know how to deal with that out of the box.

I wrote the above, using the nodejs connect and the body parser module. Want to know how to include these in your Meteor app? Look at this handy package - https://github.com/meteorhacks/npm which allows you to include NPM modules in meteor.

Look at line 15 in the above code in this gist, and you will see the key thing I had to do to get the body data to come through.

I verified this by running the following curl command:

curl -H 'Content-Type: application/vnd.contentful.management.v1+json' -d '{"status": "ok", "message": "It worked!"}' http://localhost:3000/hooks/contentful

And I got this back:

    { 
	    'user-agent': 'curl/7.30.0',
	    host: 'localhost:3000',
	    accept: '*/*',
	    'content-type': 'application/vnd.contentful.management.v1+json',
	    'content-length': '41',
	    'x-forwarded-for': '127.0.0.1',
	    'x-forwarded-port': '3000',
	    'x-forwarded-proto': 'http',
	    connection: 'keep-alive' 
    }
    
    { 
    	status: 'ok', message: 'It worked!' 
    }
if(Meteor.isServer) {
/**
* Required NPM modules
*/
var connect = Meteor.npmRequire('connect'),
Fiber = Meteor.npmRequire('fibers'),
bodyParser = Meteor.npmRequire('body-parser');
/**
* Dealing with Contentful callbacks on update of
* assets andentries an
*/
WebApp.connectHandlers
.use(bodyParser.text())
.use(bodyParser.json({type: 'application/vnd.contentful.management.v1+json'}))
.use('/hooks/contentful', function(req, res, next) {
Fiber(function() {
console.log(req.headers);
console.log(req.body);
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify({
status: 'ok',
message: 'Content updated succesfully'
}));
}).run();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment