Build an API for Multiple - c#

I'm building an API using WebAPI that will be accessed via AJAX calls. However, the API controller will need more than just one POST method. I understand I can specify {action} in my routing, but because I've seen that this is not recommended - am I using the right tool? So 2 questions:
Is Web API the best tool for this, or is there something else I should be using?
Why should I not use more than one POST method in a WebApiController? Is including {action} in my routing a good enough solution to this problem?

1. Is Web API the best tool for this, or is there something else I should be using?
I think WebAPI is a fine choice for you, regardless of whether you have one or many POST calls per controller.
2. Why should I not use more than one POST method in a WebApiController?
To remain RESTFul you'll want a controller per entity type. Without getting too deep into details, a POST against a specific type of entity should be the 'ADD entity' call, and why would you have more than one of those? Having said that, you don't have to be fully RESTFul... if your requirements suite a multi-POST model then go for it, you can always refactor later if necessary.
...Is including {action} in my routing a good enough solution to this problem?
Again, if your goal is to be RESTFul then this isn't a great practice. However, if you have needs that are best achieved using action routings then go for it. REST is not the only model.

Related

Authorization/Authentication in asp.net web api

I need to create a couple of simple methods using asp.net web api. I am very new to this so even the simplest thing is proving difficult for me. I want to decorate my api controller with [authorize] and [authenticate] for the obvious reasons.
My question is centred on how I call these methods from my ajax calls (which is how I'm intending to call them). I'm reading that I need to pass the user id and password with each of my calls but how do I do this using ajax? Or do I even need to do this manually or asp.net somehow does it for me (if that even makes any sense)? Because when I'm doing action calls that need to be authenticated/authorized using forms in mvc, I certainly don't do it expressly and I imagine somehow somewhere in the code it just gets done.
As is clear, I'm very lost. Any help is appreciated.

AngularJS and Web Service Interaction Best Practices

I have a small website I implemented with AngularJS, C# and Entity Framework. The whole website is a Single Page Application and gets all of its data from one single C# web service.
My question deals with the interface that the C# web service should expose. For once, the service can provide the Entities in a RESTful way, providing them directly or as DTOs. The other approach would be that the web service returns an object for exactly one use case so that the AngularJS Controller only needs to invoke the web service once and can work with the responded model directly.
To clarify, please consider the following two snippets:
// The service returns DTOs, but has to be invoked multiple
// times from the AngularJS controller
public Order GetOrder(int orderId);
public List<Ticket> GetTickets(int orderId);
And
// The service returns the model directly
public OrderOverview GetOrderAndTickets(int orderId);
While the first example exposes a RESTful interface and works with the resource metaphor, it has the huge drawback of only returning parts of the data. The second example returns an object tailored to the needs of the MVC controller, but can most likely only be used in one MVC controller. Also, a lot of mapping needs to be done for common fields in the second scenario.
I found that I did both things from time to time in my webservice and want to get some feedback about it. I do not care too much for performance, altough multiple requests are of course problematic and once they slow down the application too much, they need refactoring. What is the best way to design the web service interface?
I would advise going with the REST approach, general purpose API design, rather than the single purpose remote procedure call (RPC) approach. While the RPC is going to be very quick at the beginning of your project, the number of end points usually become a liability when maintaining code. Now, if you are only ever going to have less than 20 types of server calls, I would say you can stick with this approach without getting bitten to badly. But if your project is going to live longer than a year, you'll probably end up with far more end points than 20.
With a rest based service, you can always add an optional parameter to describe child records said resource contains, and return them for the particular call.
There is nothing wrong with a RESTful service returning child entities or having an optional querystring param to toggle that behavior
public OrderOverview GetOrder(int orderId, bool? includeTickets);
When returning a ticket within an order, have each ticket contain a property referring to the URL endpoint of that particular ticket (/api/tickets/{id} or whatever) so the client can then work with the ticket independent of the order
In this specific case I would say it depends on how many tickets you have. Let's say you were to add pagination for the tickets, would you want to be getting the Order every time you get the next set of tickets?
You could always make multiple requests and resolve all the promises at once via $q.all().
The best practice is to wrap up HTTP calls in an Angular Service, that multiple angular controllers can reference.
With that, I don't think 2 calls to the server is going to be a huge detriment to you. And you won't have to alter the web service, or add any new angular services, when you want to add new views to your site.
Generally, API's should be written independently minded of what's consuming it. If you're pressed for time and you're sure you'll never need to consume it from some other client piece, you could write it specifically for your web app. But generally that's how it goes.

Versioning REST API of an ASP.NET MVC application

I'm looking at developing an application in ASP.NET MVC 3 and would like to provide a public API at the same time.
From looking around, there seems to be 2 ways to go about it. Either create an API area and have controllers that return json / xml. Or use action filters and a single front end set of controllers, and have those return json / xml / html depending on the request headers.
I'd like to do the later, but I was wondering how you could go about versioning your api if you went this route?
If you go the first route, you could easily just create a v1 / v2 controller, but if you do the later, how could you version it?
Versioning is a rather complex issue to begin with. Here are ways I looked at before:
URL. In this case https://api.example.com/v1/projects is assumed to be a different resource than http://api.example.com/v2/projects, even though its not the case. Basecamp seems to do this. Following this approach, assume you'll always have to support old APIs.
Headers. The URLs remains the same, however, the client pass an additional HTTP header, say X-MYAPI-VERSION with each request with a value identifying the version of the API to use. The Google Documents List API do this. A potential problem with this approach is that HTTP headers may be stripped by intermediaries between the client and server.
Parameters. To circumvent the problem with option 2, you can pass the API version to use as a parameter (such as https://api.example.com/projects?v=3).
Media types. Here your URLs stay the same, however, users are required to specify the representation of the resources using the accept and content type headers. For example, a "project" can be presented using "application/vnd.mycompany.resource[-version][+format]" giving your representations of "application/vnd.mycompany.project-v1+json" for v1 json or "application/vnd.mycompany.project-v1+xml" for v1 xml. When you need a new version of a project comes along the mime type may look as follows "application/vnd.mycompany.project-v2+xml". Github seems to support that.
Part of payload. In this case the payload of the request contains the version number to use. For example, when XML is passed, you can look at the namespace to determine which version of the API is being used. For JSON, you can use a "$version" or "_version" property to specify the version.
Client Key. When the application is registered, it specifies which version of the API it wants to use. When you authenticate the client, you ensure that you emulate the version it wants to use.
No explicit versioning There is always the option not to version your API and try to handle changes transparently by making all fields optional and handle them appropriately when they are missing. Chances are you will be doing this anyways to make future versions of your API compatible with the version you are developing today.
Many recommend option 4, although its not always practical. Most of these options require additional work to get working with ASP.NET MVC.
You can go one of two routes - you can include the API in the route (instead of http://app.lication/category/1 you would have something like http://app.lication/api/v1/category/1) or you could include a custom HTTP header.
Either will allow you to discriminate which version's being called.

REST based MVC site and/or WCF

I know there are actually a number of questions similar to this one, but I could not find one that exactly answers my question.
I am building a web application that will
obviously display data to the users :)
have a public API for authenticated users to use
later be ported to mobile devices
So, I am stuck on the design. I am going to use asp.net MVC for the website, however I am not sure how to structure my architecture after that.
Should I:
make the website RESTful and act as the API
in my initial review, the GET returns the full view rather than just the data, which to me seems like it kills the idea of the public API
also, should I really be performing business logic in my controller? To be able to scale, wouldn't it be better to have a separate business logic layer that is on another server, or would I just consider pushing my MVC site to another server and it will solve the same problem? I am trying to create a SOLID design, so it also seems better to abstract this to a separate service (which I could just call another class, but then I get back to the problem of scalability...)
make the website not be RESTful and create a RESTful WCF service that the website will use
make both the website and a WCF service that are restful, however this seems redundant
I am fairly new to REST, so the problem could possibly be a misunderstanding on my part. Hopefully, I am explaining this well, but if not, please let me know if you need anything clarified.
I would make a separate business logic layer and a (restful) WCF layer on top of that. This decouples your BLL from your client. You could even have different clients use the same API (not saying you should, or will, but it gives you the flexibility). Ideally your service layer should not return your domain entities, but Data Transfer Objects (which you could map with Automapper), though it depends on the scope and specs of your project.
Putting it on another server makes it a different tier, tier <> layer.
Plain and simple.... it would be easiest from a complexity standpoint to separate the website and your API. It's a bit cleaner IMO too.
However, here are some tips that you can do to make the process of handling both together a bit easier if you decide on going that route. (I'm currently doing this with a personal project I'm working on)
Keep your controller logic pretty bare. Judging on the fact that you want to make it SOLID you're probably already doing this.
Separate the model that is returned to the view from the actual model. I like to create models specific to views and have a way of transforming the model into this view specific model.
Make sure you version everything. You will probably want to allow and support old API requests coming in for quite some time.... especially on the phone.
Actually use REST to it's fullest and not just another name for HTTP. Most implementations miss the fact that in any type of response the state should be transferred with it (missing the ST). Allow self-discovery of actions both on the page and in the API responses. For instance, if you allow paging in a resource always specify in the api or the webpage. There's an entire wikipedia page on this. This immensely aids with the decoupling allowing you to sometimes automagically update clients with the latest version.
Now you're controller action will probably looking something like this pseudo-code
MyAction(param) {
// Do something with param
model = foo.baz(param)
// return result
if(isAPIRequest) {
return WhateverResult(model)
}
return View(model.AsViewSpecificModel())
}
One thing I've been toying with myself is making my own type of ActionResult that handles the return logic, so that it is not duplicated throughout the project.
I would use the REST service for your website, as it won't add any significant overhead (assuming they're on the same server) and will greatly simplify your codebase. Instead of having 2 APIs: one private (as a DLL reference) and one public, you can "eat your own dogfood". The only caution you'll need to exercise is making sure you don't bend the public API to suit your own needs, but instead having a separate private API if needed.
You can use RestSharp or EasyHttp for the REST calls inside the MVC site.
ServiceStack will probably make the API task easier, you can use your existing domain objects, and simply write a set of services that get/update/delete/create the objects without needing to write 2 actions for everything in MVC.

Getting rid of the /Home path name in ASP.NET MVC

I’ve only just started using ASP.NET MVC, and I have a somewhat trivial question: it seems that each controller has an attached folder-like path, so that my site becomes mydomain.net/Home/something. Is it possible to somehow get rid of the /Home part, so that the Home controller becomes ‘default’ for my web site and it’s possible to just use mydomain.net/something instead?
Sure, just define a route like so:
routes.MapRoute("{action}/{id}", new {controller="Home", action="Index", id=""});
The only problem is what about requests for your other controllers? For example, is
/Product/Foo
A request for HomeController.Product("Foo") or ProductController.Foo()?
You might need to use constraints to make the distinction clear.
I did a blog post on a simple way to handle this. I created a route constraint that selects a controller that you want to use for the root of your site. Here is the blog post if you're interested.

Categories

Resources