Multiple GET routes with different parameters - angularjs

does anyone know if u can and if its good practice to define multiple GET routes such as:
GET: '/channels' returns all channels in the app
GET: '/channels/:username' returns all channels created by a user
GET: '/channels/:channelname' return details about a channel
POST: '/channels' creates a new channel
PUT: '/channels/:channelname' edits a channel with the name ':channelname'
What im confused is the third GET route. Don't know if it's possible or if theres a better way to do it..

You cannot have multiple routes with the same parameter.
I think that the most logical way is to do this :
GET: '/channels/user/:username' returns all channels created by a user

You couldn't use same verb (get, post, put ..) for same route. You can use same verb for different route or same route for different verb.
in your problem used
GET: '/channels/:username' and
GET: '/channels/:channelname'
both act as a same thing because when you request by /channels/somename fro client site then valid for both routes because username can be somename or channelname can be somename.
so to differentiate two routes need to change your any one route. like
GET: '/channels/user/:username' // that different from /channels/:channelname
for node.js and express you can use like:
var router = express.Router();
router.route('/place')
.get(placeController.getPlaces)
.post(placeController.createPlace);
router.route('/place/:placeId') // same route for different verb
.get(placeController.getPlaceById)
.put(placeController.updatePlaceById)
.delete(placeController.deletePlaceById);
router.route('/hotel/:placeId') // here :placeId params name same for both but /hotel differentiate from /place
.get(hotelController.getHotelById)
.put(hotelController.updateHotelById)
.delete(hotelController.deletHotelById);

Related

How to dynamically return a from endpoint in apache camel DSL

Here is my code
from("google-pubsub:123:subscription1?maxMessagesPerPoll=3 & concurrentConsumers=5" ).routeId("myroute")
.process(new ProducerProcessor())
to("google-pubsub:123:topic1")
;
In my code above ,the from channel I want to make it generic.Basically it should be able to consume data from good-pubsub or may be from a file or from a JMS queue.Hence depending upon a parameter I want to return
a different from channel.Something like below
private RouteDefinition fromChannel(String parameter) {
if (parameter is "google" then
return from("google-pubsub:123:subscription1?maxMessagesPerPoll=3 & concurrentConsumers=5" )
if (parameter is "file" then
return from(/my/fileFolder/)).split(body().tokenize("\n")).streaming().parallelProcessing();
}
I tried this but I am getting null pointer exception in the fromChannel method.Please let me know if you have better ideas.
Rewrite based on comment
You can for example create a (static) template route for every input type and generate the routes based on a configured endpoint list.
I described such an endpoint configuration and route generation scenario in this answer.
Like this you can generate the split part for every file route and any other specialty for other route types.
All these input routes are routing at their end to a common processing route
.from(pubsubEndpoint)
.to("direct:genericProcessingRoute")
.from(fileEndpoint)
.split(body()
.tokenize("\n"))
.streaming()
.parallelProcessing()
.to("direct:genericProcessingRoute")
.from("direct:genericProcessingRoute")
... [generic processing]
.to("google-pubsub:123:topic1")
The multiple input (and output) routes around a common core route is called hexagonal architecture and Camel fits very well into this.

Multiple get API in MEAN.IO (Express, Angular)

In traditional REST API, we should define our API like this:
GET /api/things -> get all
POST /api/things -> create
GET /api/things/:id -> get one
PUT /api/things/:id -> update
DELETE /api/things/:id -> delete
How should i define another 'get one' endpoint for querying data by any other field other than id? For example:
GET /api/things/:title -> get one by title (this sure does not work since the api isn't aware of URL parameter names)
GET /api/things/title/:title ? this does not work for me at all..
GET /api/things?title=whatever (this cannot be defined at all. When i write this in my index.js:
router.get('?title=whatever', controller.getByTitle);
I get this:
SyntaxError: Invalid regular expression: /^?title=whatever\/?$/: Nothing to repeat
at RegExp (native)
ID should be an unique identifier. Given one ID, you should return one resource at most. That's why an URI like GET /api/things/:id makes sense.
For other properties which may or may not be unique, you can have more than one result, so use the GET /api/things endpoint and pass query parameters : /api/things?title=mytitle.
app.get('/api/things', function (req, res) {
console.log(req.query.title); //mytitle
ThingModel.find({
title: req.query.title
}, function (err, things) {
res.send(things);
});
});

What is the use of 'Route' in Restangular functions oneUrl() and allUrl()

That's the signature for oneUrl function: oneUrl(route, url)
And from the documentation:
oneUrl(route, url): This will create a new Restangular object that is
just a pointer to one element with the specified URL.
To me, it seems useless to set Route when you are giving a url for the resource. Why does it exist in the argument list? Why is it mandatory? And how can it be used?
In my use of oneUrl I've found the route name is used to build the URL for subsequent PUT and DELETE operations. For example (pseudo code):
// "GET /api/v2/users/3/ HTTP/1.1" 200 184
var user = Restangular.oneUrl('myuser', 'http://localhost:8000/api/v2/users/3').get();
user.name = 'Fred';
// the following uses the route name and not the URL:
// "PUT /api/v2/myuser HTTP/1.1 404 100
user.put();
I was surprised by this behavior. I expected put() to use the same URL as get(); which would be helpful in my case.
My API uses absolute URLs within the JSON payloads to navigate to all related resources and I wanted to use oneUrl() to GET/PUT instances without recreating the routes in the JS code. But I'm pretty new to Restangular so I might not have the mental model correct.

node.js, restify - handle a parameter of type array

I have a node.js server with restify. I want to send it a get request that has an array of names in it. I think the request should look like this (but I am not sure about it):
/users?names=bob,joe,michael,joey
Is this query correct?
How do I get the names I send on the node.js server?
The W3C recommendation is that one key can be repeated multiple times with multiple values:
GET /users?names=bob&names=joe&names=michael&names=joey
Good systems will be designed to handle this format of data and be able to recognize multiple keys to group them within an array.
You do not need to specify query variables in your route:
// perform: GET /users?names=bob&names=joe&names=michael&names=joey
server.get('/users', function (req, res) {
// All your query vars from the GET request are in req.query
res.json(req.query.names);
});

Router in backbone not handling route after initialization

I have multiple routers in my app, in general way it looks like this:
// Start backbone.js
if (!Backbone.History.started) {
Backbone.history.start({pushState: true, hashChange: false});
}
// Perform some RPC requests ...
// Depending on user role, received from the server should be created suitable router:
var router;
if (typeof app.user.role === 'manager') {
router = new routers.manager();
} else {
router = new routers.guest();
}
Problem is that after page is loaded and script is executed routers do not do. anything. They do not load route for current url automatically. So, i had to fix it this way (i am not sure that it is a right way):
routers.guest.initialize = routers.manager.initialize = function() {
var defaultRoute = 'default';
if (typeof this.routes[Backbone.history.fragment] !== 'undefined') {
this[this.routes[Backbone.history.fragment]]();
} else {
this.navigate(defaultRoute, true);
}
};
It is working fine, except one bug: when i use route with params, for example /reset-password-confirm/:code - it is unable to find in in routes property. I could write some more code to fix it, but i suppose that i am doing something wrong, if i have to write such things - as i understand router should handle routes just after it was created.
So, questions:
Why my router(s) does not handle routes for current url after it is being created? Perhaps i need to start backbone history later? (but this bug will happen again later then)
How it is possible to make routes with params like /user/:id work there?
Perhaps it is bad idea to re-create routers? Perhaps it is better to create all of them one time?
P.S. I've tried to create both routers and keep them, also i've trie to call backbone history start method after all routers were created.. but this didn't help :/
Assuming you route is declared as the following:
routes : {
'/user/:id' : 'user'
}
Your initialize code is not working because when you initialize your router with a url such as: /user/1234. Backbone.history.fragment will be /user/1234 (not /user/:id). Since the this.routes object doesn't have a key of /user/1234, your else clause calls the default route.
If you first instantiate your router then call Backbone.history.start(), you will be able to remove your router initialize code. When you navigate to a url as /user/1234 your router will match the /user/:id route and call the user function.
The following should work for you without adding your initialize code:
var router = (app.user.role === 'manager') ? new routers.manager()
: new routers.guest();
Backbone.history.start({pushState: true, hashChange: false});
Looking at the code, seems like you're starting the backbone history before initializing any routes. That's most likely not goning to work.
The correct way of doing this type of seperation is by creating all the routes based on the role received from the server and then start the backbone history. Here's an SO thread that talks about it with code samples as well : How to protect routes for different user groups

Resources