I'm using flow router for client side routing in a Meteor app. I need to use a router on the server side to expose a webhook. So, I plugged in iron router, but iron router now injects html into my app complaining I need to configure routes in the app. I guess it thinks at least one client side route should exists, er? I have implemented one iron router route in the server like so:
Router.map(function() {
this.route('webhooks', {
layoutTemplate: null,
path: '/webhooks/:source',
where: 'server'
})
.post(function() {
// auth, stuff happens, etc //
this.response.end('Thank you, come again!');
});
});
Is there some configuration I can add to iron router that tells it to calm down?
You may want to use Picker instead
https://github.com/meteorhacks/picker/
It is designed as a dedicated server side router for meteor.
Also recommended by FlowRouter https://kadira.io/academy/meteor-routing-guide/content/server-side-routing-rest
Related
When component introduces new route for its router-view it is working while going trough the app, but once you refresh or try to access url directly it does not load. I assume that it is because of the fact that component adding routes did not add them yet.
But I would expect that router would parse url by its segments, match parent component, loads it (which introduces child routes) and then continue with next segment. Or something similar.
Is there a way how to achieve routing added lazily? So each loaded module introduce its part (module) of a router? But in same time they can be accessed by url?
Thanks
Here is reproduced issue: https://codesandbox.io/s/vue-3-router-lazy-route-5opufo
Click on Admin link and then settings, it works, try to access admin/settings by url, it does not load settings content.
EDIT:
Here what I expect https://stackblitz.com/edit/angular-vwnzjg
ATTENTION it fails on stackblitz, but you can download the project, install dependencies and try it yourself to see that it works correctly.
After start dev server, navigate directly to http://localhost:4200/customers/profile as you can see, it works even the fact that the router part targeted is loaded lazily in Customers module.
When you click on admin and then click on settings, the code run follows this scenario:
Click admin -> router resolved (found admin component) -> admin component setup -> you dynamic add settings router
-> click settings -> router resolved (found settings component) -> load settings component successfully
But when you reload the browser on the /admin/settings route, the scenario will be:
Reload page '/admin/settings' -> router resolved (found admin component but NOT the settings component because admin component's setup code is not run yet)
-> only load admin component
In this scenario, the admin component's setup code will be run after the router is resolved. So the dynamic adding router code is not run at that time and the router can NOT resolve the settings component
Solution
Move your dynamic adding router code to beforeEach navigation guard so it can be run every time the router resolved
router.beforeEach((to, from) => {
const hasRoute = router.hasRoute(to.name || "");
if (to.path === "/admin/settings" && !router.hasRoute(to.name || "")) {
router.addRoute("admin", {
path: "settings",
name: "settings",
component: { template: "<div>AdminSettings</div>" }
});
// Don't forget to return the router here to make sure the router will be correctly resolved
return { name: "settings" };
}
});
I can successfully send a web hook from Stripe to my Meteor app in development using ngrok. For example, my test endpoint on the Stripe dashboard would be sent to something like https://f5f62fdf.ngrok.io. It responds with a successful notice. The ngrok inspector shows the stripe test object received. But in Meteor I'm a little unsure how the router should look with ngrok. On the server, my route would be something like:
Router.route( "<unsure what path to put here>", function() {
console.log('hello');
}, { where: "server" });
In my testing environment using ngrok, what would the path be?
Just trying to get the function to console.log() my 'hello' so I know it's working.
OK, I'm an idiot. It console.logs to the terminal, not the browser. Ouch. Given I'm working with Node, it makes sense. Just for posterity, the Stripe endpoint would be something like https://g4r62fdf.ngrok.io/stripe/webhook.
Make sure you're returning a response inside the function so the web hook won't timeout.
this.response.statusCode = 200;
this.response.end('10-4, good buddy');
I'm trying to accept a post request from my twilio account to my application to get an xml response back. How do I respond to an incoming post request in iron router? I have read the docs and tried everything in there but I just get (Error: Not implemented on server yet). I have tried putting it on the server, on the client and in lib.:
Router (lib/router.coffee)
Router.route('/api/twilio/voice', where: 'server')
.post -> console.log 'hey'
This is due to having this.subscribe then .wait()s configured for both server and client. Look for .wait within your Router configuration scopes and make sure it only runs at the client.
Look at the code part where this happens at the iron-controller repo:
https://github.com/EventedMind/iron-controller/blob/devel/lib/controller_server.js
Also I think a better way to debug (instead of console.log) is to actually use this.response:
Router.route('/api/twilio/voice', { where: server })
.post(function() {
this.response.end('hey');
});
or even the classic format:
Router.route('/api/twilio/voice', { where: server })
.post(function(req, res, next) {
res.end('hey');
});
Edit: Issue filed here and PR here.
Using Iron Router I can add a route such as /index returns "INDEX CONTENT" from the server:
this.route('index', {
path: '/',
where: 'server',
action: function () {
this.response.end("INDEX CONTENT");
}
});
The default behaviour for a Meteor app is to return a boilerplate HTML file on the initial request to the server which contains the js/css etc required to run the web app.
What I would like to do, however, is place a string (ie "INDEX CONTENT" as above) within the boilerplate which would normally be returned by default if I hadn't added the route. To do this, I'd need to be able to modify a boilerplate response before it is sent to the client but after it is constructed by the standard meteor response mechanism.
Can anyone recommend a way to be able to do this?
You could try the inject-initial meteorite package.
From the docs:
Inject.rawModHtml(id, func). At injection time, calls func(html, res) with the full page HTML which it expects to be returned, in full, after modification. res is the current http connection response request.
I think you would use it like this.
Inject.rawModHtml('breakEverything', function(html) {
return "INDEX CONTENT";
});
I am planning to use Meteor for a realtime logging application for various
My requirement is pretty simple, I will pass a log Message as request Parameter ( POST Or GET) from various application and Meteor need to simply update a collection.
I need to access Request Parameters in Meteor server code and update Mongo collection with the incoming logMessage. I cannot update Mongo Collection directly from existing applications, so please no replies suggesting the same.I want to know how can I do it from Meteor framework and not doing it by adding more packages.
EDIT: Updated to use Iron Router, the successor to Meteor Router.
Install Iron Router and define a server-side route:
Router.map(function () {
this.route('foo', {
where: 'server',
action: function () {
doSomethingWithParams(this.request.query);
}
});
});
So for a request like http://yoursite.com/foo?q=somequery&src=somesource, the variable this.request.query in the function above would be { q: 'somequery', src: 'somesource' } and therefore you can request individual parameters via this.request.query.q and this.request.query.src and the like. I've only tested GET requests, but POST and other request types should work identically; this works as of Meteor 0.7.0.1. Make sure you put this code inside a Meteor.isServer block or in a file in the /server folder in your project.
Original Post:
Use Meteorite to install Meteor Router and define a server-side route:
Meteor.Router.add('/foo', function() {
doSomethingWithParams(this.request.query);
});
So for a request like http://yoursite.com/foo?q=somequery&src=somesource, the variable this.request.query in the function above would be { q: 'somequery', src: 'somesource' } and therefore you can request individual parameters via this.request.query.q and this.request.query.src and the like. I've only tested GET requests, but POST and other request types should work identically; this works as of Meteor 0.6.2.1. Make sure you put this code inside a Meteor.isServer block or in a file in the /server folder in your project.
I know the questioner doesn't want to add packages, but I think that using Meteorite to install Meteor Router seems to me a more future-proof way to implement this as compared to accessing internal undocumented Meteor objects like __meteor_bootstrap__. When the Package API is finalized in a future version of Meteor, the process of installing Meteor Router will become easier (no need for Meteorite) but nothing else is likely to change and your code would probably continue to work without requiring modification.
I found a workaround to add a router to the Meteor application to handle custom requests.
It uses the connect router middleware which is shipped with meteor. No extra dependencies!
Put this before/outside Meteor.startup on the Server. (Coffeescript)
SomeCollection = new Collection("...")
fibers = __meteor_bootstrap__.require("fibers")
connect = __meteor_bootstrap__.require('connect')
app = __meteor_bootstrap__.app
router = connect.middleware.router (route) ->
route.get '/foo', (req, res) ->
Fiber () ->
SomeCollection.insert(...)
.run()
res.writeHead(200)
res.end()
app.use(router)
Use IronRouter, it's so easy:
var path = IronLocation.path();
As things stand, there isn't support for server side routing or specific actions on the server side when URLs are hit. So it's not easy to do what you want. Here are some suggestions.
You can probably achieve what you want by borrowing techniques that are used by the oauth2 package on the auth branch: https://github.com/meteor/meteor/blob/auth/packages/accounts-oauth2-helper/oauth2_server.js#L100-109
However this isn't really supported so I'm not certain it's a good idea.
Your other applications could actually update the collections using DDP. This is probably easier than it sounds.
You could use an intermediate application which accepts POST/GET requests and talks to your meteor server using DDP. This is probably the technically easiest thing to do.
Maybe this one will help you?
http://docs.meteor.com/#meteor_http_post