MapHttpRoute for specified controller - web-services

I created a WebApi 2 web service.
To support routing more complex than the default one for some endpoints, I add something like:
config.Routes.MapHttpRoute(
name: "StatusApi",
routeTemplate: "api/{controller}/Status/{status}",
defaults: new { status = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DisplayUnitApi",
routeTemplate: "api/{controller}/DisplayUnit/{unit}",
defaults: new { status = RouteParameter.Optional }
);
I meant these new routes not for all the endpoints, but only for some of them.
Unfortunately now all the endpoints support these routing, but I prefer to keep the new routing only for my chosen endpoints.
Is it possible to be selective?
An example:
POST api/DoAction
POST api/DoAction/Status
POST api/DoAction/Name/{unit}
Before adding the new routes, the only available was POST api/DoAction. For this controller, I'd like to keep only the original endpoint reachable.
Thanks,
Roberto

Try below code
config.Routes.MapHttpRoute(
name: "StatusApi",
routeTemplate: "api/{controller}/Status/{status}",
defaults: new { controller = "xxxx", action = "yyyyy" });
config.Routes.MapHttpRoute(
name: "DisplayUnitApi",
routeTemplate: "api/{controller}/DisplayUnit/{unit}",
defaults: new { controller = "xxx", action = "yyyyy" });

In Web API 2 you have attibute routing:
http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
Therefore you route maps to the general default routes and the and the specific actions attibute them to what you desire:
[httpPost, Route("api/DoAction")]
[httpPost, Route("api/DoAction/Status]
[httpPost, Route("api/DoAction/Name/{unit}]

Related

Include Stripe in angular project

I am working on a website which uses angular for client and django for backend and I want to include stripe for payments. To configure stripe on the backend I have a microservice which runs on docker and accepts the following requests:
one for creating a stripe customer
another one for creating a payment
I configured stripe on the client using the provided form as follows:
export class PaymentComponent implements OnInit {
paymentHandler:any = null;
constructor(private checkoutService: CheckoutService) { }
ngOnInit() {
this.invokeStripe();
}
initializePayment(amount: number) {
const paymentHandler = (<any>window).StripeCheckout.configure({
key: 'pk_test_51MKU1wDo0NxQ0glB5HRAxUsR9MsY24POw3YHwIXnoMyFRyJ3cAV6FaErUeuEiWkGuWgAOoB3ILWXTgHA1CE9LTFr00WOT5U5vJ',
locale: 'auto',
token: function (stripeToken: any) {
console.log(stripeToken);
alert('Stripe token generated!');
paymentStripe(stripeToken);
}
});
const paymentStripe = (stripeTocken: any) => {
this.checkoutService.makePayment(stripeTocken).subscribe((data:any) => {
console.log(data)
})
}
paymentHandler.open({
name: 'Card Details',
description: 'Introduce the information from your card',
amount: amount * 100
});
}
invokeStripe() {
if(!window.document.getElementById('stripe-script')) {
const script = window.document.createElement("script");
script.id = "stripe-script";
script.type = "text/javascript";
script.src = "https://checkout.stripe.com/checkout.js";
script.onload = () => {
this.paymentHandler = (<any>window).StripeCheckout.configure({
key: 'pk_test_51MKU1wDo0NxQ0glB5HRAxUsR9MsY24POw3YHwIXnoMyFRyJ3cAV6FaErUeuEiWkGuWgAOoB3ILWXTgHA1CE9LTFr00WOT5U5vJ',
locale: 'auto',
token: function (stripeToken: any) {
console.log(stripeToken)
alert('Payment has been successfull!');
}
});
}
window.document.body.appendChild(script);
}
}
}
The makePayment method makes a request to the django server sending the stripe tocken.
From the server I need the above requests to the microservice.
My question is why do I need the configurations from the server as long as all I have to do to perform a payment is to make a request to the microservice? And where should I use the tocken.
I have also read about webhooks, but I don't really understand the concept and how to use this in my situation.
Also, do I need to test everything with angular cli? And why?
Thank you in advance!

Loopback: How to add afterRemote of a model to another model

I have Notification model which looks like this
"use strict";
module.exports = function(Notification) {
};
And I have another model which is Post:
"use strict";
module.exports = function(Post) {
Post.prototype.postLike = function(options, cb) {
this.likes.add(options.accessToken.userId);
cb(null, "sucess");
};
Post.remoteMethod("postLike", {
isStatic: false,
accepts: [{ arg: "options", type: "object", http: "optionsFromRequest" }],
returns: { arg: "name", type: "string" },
http: { path: "/like", verb: "post" }
});
}
What I want is to add afterRemote method of Post inside of notification model ?
Is it possible in loopback ?
It should looks like :
"use strict";
module.exports = function(Notification) {
var app = require("../../server/server.js");
var post = app.models.Post;
post.afterRemote('prototype.postLike', function(context, like, next) {
console.log('Notification after save for Like comment');
});
};
But this does not work.
NOTE: I can do it Post model itself, but I want to add all of my notification logic in Notification model for simplification and future customization.
You can use events to do.
Loopback application emits started event when it started after all boot scripts loaded here
and in Notification model do like this :
"use strict";
module.exports = function(Notification) {
var app = require("../../server/server.js");
app.on('started', function(){
var post = app.models.Post;
post.afterRemote('prototype.postLike', function(context, like, next) {
console.log('Notification after save for Like comment');
});
});
};
Or create a boot script and emit a custom event like 'allModelsLoaded'. So make sure the boot script is the last one to be run. Boot scripts run in alphabetic order by default. So make z.js and emit that custom event there then listen to that event in Notification model.
Loopback boot process first loads models, and then invoke boot scripts once all models have been loaded. If your aim is to consolidate things across models, then it is better to do this in a boot script, rather than in model.js file.

How to define separate hidden props for GET and POST methods in loopback?

I want some props to be visible for GET method in loopback explorer, but I don't want to show them for POST method, for e.g. id property. How it can be done in loopback?
There are no built-in methods for this.
You need to do it in after remote for each remote method you want to be different from the default.
Model.afterRemote('GetMethod', function(ctx, instance, next){
var instance = ctx.result;
//reshape it
ctx.result = instance;
next();
});
UPDATE
If you want to affect this in explorer component so you need to create separate models with null datasource just for showing schema and use that in definition of remote method.
Model.remoteMethod('GetMethod', {
accepts: [
{
arg: 'req',
type: 'Object',
required: true,
http: {source: 'req'}
}
],
returns: {root: true, type: 'ModelDTOForSHow'},
http: {verb: 'get', status: 200, path: '/getter'}
});
And in ModelDTOForShow you hide some props and in another one some other props

Set cookie for domain instead of subDomain using NodeJS and ExpressJS

I have been using expressjs and mongostore for session management. Following is the code to configure store in expressjs,
app.configure(function(){
app.use(express.session({
secret: conf.secret,
maxAge: new Date(Date.now() + 3600000),
cookie: { path: '/' },
store: new MongoStore(conf.db)
}));
});
I had mentioned the cookie path in the above code. But it sets the cookie in sub.domain.com instead of .domain.com. How do i achieve this?
configure it like this:
app.use(express.session({
secret: conf.secret,
cookie: { domain:'.yourdomain.com'},
store: new MongoStore(conf.sessiondb)
}));
Try to use the following link to configure.
res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true });
Link : http://expressjs.com/api.html#res.cookie
This won't work, it throws error.
Error: Most middleware (like session) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
app.use(express.session({
secret: conf.secret,
cookie: { domain:'.yourdomain.com'},
store: new MongoStore(conf.sessiondb)
}));
I have a reference link, from where you can take help to set domain in cookie
https://flaviocopes.com/express-cookies/

asp.net mvc routing and the mysterious 404

I am new to .net mvc.
In a nutshell, I want to see my website so people can type:
mywebsite/John#Eric
and get processed by the correct controller.
On the other hand, I'd like to be able to also specify direct actions such as:
mywebsite/GetPeople
and get proccessed by GetPeople action.
I have set up two routing rules in my application:
First Route
routes.MapRoute("Default",
"{id}",
new { controller = "Friends", action = "Index", id = UrlParameter.Optional },
new { controller = #"[^\.]*", id = #"(?i)[a-z]*#[a-z]*" }
);
Second Route
routes.MapRoute(
"Friends",
"{action}/{id}",
new { controller = "Friends" }
);
The first and default route works great, but then when I send a request like this: mywebsite/GetPeople
the cheacky index action takes over and reads GetPeople as if it were a parameter. Even though I added my real awesome regax, this doesn't seem to work.
Any ideas ?
Here's how your routes might look:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Friends",
"{id}",
new { controller = "Friends", action = "Index", id = UrlParameter.Optional },
new { id = #"(?i)[a-z]*#[a-z]*" }
);
routes.MapRoute(
"Default",
"{action}/{id}",
new { controller = "Friends", action = "Index", id = UrlParameter.Optional }
);
}
Now mywebsite/John#Eric will be handled by the Index action of the Friends controller and mywebsite/GetPeople will be handled by the GetFriends action of the Friends controller.
That is because of the way routing works in MVC. It just matches incoming URLs with routes in the order the routes are declared in RegisterRoutes. In this case the GetPeople in the URL would match with the Id parameter as everything is optional. To fix this, I would add a default as the last route. It could be done as so
routes.MapRoute("", "{controller}/{action}", new { controller = "Friends",action="Index" });
This would handle the GetMyPeople URL. You would need to have an Index action on it though. The MvcContrib has an excellent Test helper for testing out MVC routes before actually running it from the app. You can get the bits here