How to write REST Web services in Laravel 5.2? - rest

I am creating api for mobile app in laravel 5.2 version but now I am facing one problem. Problem is that in my routes.php I am created routes for my website. Now my question is if I start creating api for mobile for that I have to create new routes for mobile api Or I can use same routes for RESTapi also?
In Laravel 5.2 I have to add any webservices libraries or not? If yes, Please suggest me how to use RESTapi in Laravel 5.2? Please help.
My routes.php
Route::auth();
Route::get('/', 'Auth\AuthController#login');
Route::get('admin/users', 'UserController#getUsers');
Route::get('admin/users/add', 'UserController#addUser');

If your routes an their inside logic returns json response, Its not necessary to create new routes, But if your routes does not returns json response, you must write new routes.
For having better APIs, json-hal, jsend or json-api conventions may help you.

Your api routes can coexist with your regular web routes. It's customary, however, to separate them, typically by a subdomain (https://api.yoursite.com), or at least a path (https://yoursite.com/api/v1).
Also, api version number is often included, as in my last example.
As for a package to develop apis in Laravel, have a look at Dingo. It's very complete, provides its own router, versioning, security, etc.

You have different middleware in laravel. By default you should have "web" middleware activated. It is either directly in your routes.php, in your controler constructor OR in the RouteServiceProvider.php
You wouldn't use web middleware for an api / restful service, therefore you should use another middleware ( e.g. "api" middleware which throttles requests to only allow max. 60 requets per minute etc. )
Typically you group your api requests
Route::group(['prefix' => 'api/v1'], function()
{
...
}
to strictly divide them from your application. You can then also easy change to v2 for example if you plan many releases
Update
if your api logic follows your business logic then you could aswell just watch for ajax calls and return json
public function index(Request $request) {
// do stuff here
if($request->ajax()) {
// return json
}
// return view
}

Related

How to implement restful API with additional noun for entity

I would like to implement the following restful API using sails js:
(https://blog.codecentric.de/en/2012/11/a-restful-learning-curve-nouns-verbs-hateoas-and-roca/)
…/customers/[customer_id]/approval
I will PUT method to send approval information, and GET method to get the approval status.
It is quite easy in Sails js to implement in the following way:
…/customers/approval/[customer_id]
I only need to add a method approval in CustomerController.js. But if I want to implement the first approach (i.e. [customer_id] followed by approval. How can I do that in Sails js?
By the way, which API style is better?
You would need to write your own route
/customers/:customer_id/approval : 'CustomerController.approval'
Then inside your controller/action you would have access to req.param.customer_id
Checkout these links
http://sailsjs.org/documentation/concepts/routes
http://sailsjs.org/documentation/concepts/routes/custom-routes

CakePHP 3 allow only REST index.json and and.json (no normal views) with Auth

I've created the blog from blog tutorial, and I would to protect articles list, but I want that this be accesible across REST, I've activated json extensions.
All works well. I can add and retrieve list, but now I want to deny index and add from web and only be accesible from .json to public.
I tried with
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow('index.json');
}
But this obviously doesn't work. All webpage is login protected as is in tutorial. Web services should be accesible to Android App (code is ready and working).
Thank you!
Of course that doesn't work, the allow() methods expects valid method names, and that's all the authentication component cares about, method/action names, it doesn't matter how the action was requested.
What you are trying to do requires you to check the type of the request, and based on the results, allow the actions. Checking the request type can be done using Request::is().
See Cookbook > Request & Response Objects > Checking Request Conditions
So it might be as simple as
if ($this->request->is('json')) {
$this->Auth->allow(['index', 'add']);
}

Can grails application have RestController and normal controller (for GSP) for same domain class

Recently I need to create REST API for existing grails application.
I am thinking that is it really possible to have both of the controllers (Normal and Restful) for same domain class in one single grails application?
Which controller will handle the request if make a HTTP GET request?
Please discuss your thoughts or if it is possible at all please guide me how.
We can define a new Controller to handle to REST API calls. e.g. In my app I have User as Domain Class and have UserController which return the data to GSP pages. I wanted to add REST API support (unfortunately) in the same app and I don't wanted to deal with mess it is already there in UserController. So I added new Controller UserRestController which will specifically handle the REST API calls and following mapping in UrlMappings.groovy which now works fine. Thanks to #codehx for helping me on this.
"/api/users"(controller: "userRest", parseRequest: true) {
action = [GET: "list", POST: "save" }
"/api/users/$id"(controller: "usersRest", parseRequest: true) {
action = [GET: "show", PUT: "update", DELETE: "delete"] }
Which controller will handle the request if make a HTTP GET request?
As far as it is not possible to have two controllers with same name in grails app this will not be confusing.
Just use two different names for Normal controller and for your RESTFUL controller, so obviously the URL for accessing the two urls will be different.

Ember Model RESTAdapter nested endpoint

I'm building a web app using Ember 1.5 and I use Ember Model 0.0.11 to link the app to an API. I'm currently having trouble getting Ember Model to use nested API endpoints.
For instance, my app has a User model, which has a hasMany relationship with a Post model. Now, when I want to load the posts for a certain user, I'd like the Post.findQuery('user_id', {user_id}); method to access the GET /users/{user_id}/posts endpoint. Instead, it seems that the Ember Model solution prefers to send the query as a parameter to the GET /posts endpoint.
Ember Model's RESTAdapter does allow for easy customization, but before I start coding a completely custom RESTAdapter I'd love to know if someone has already done this and how they solved the problem.
The solution for us to handle nested API routes was to have a links hash returned with the requested payload. If you can change the API output, this is the way to go for now. For example, when requesting a workspace, the returned JSON looks like this (excuse the escaped characters):
{
"data":
{
"object":"workspace",
"id":"wrk_krVZWGaJ",
"organization_name":"Legros, Klein and Boehm",
"workspace_name":"Legros, Klein and Boehm",
"workspace_path":"legros, klein and boehm",
"status":true,
"credit_production":7,
"credit_revision":16,
"links":{
"projects":"\/v1\/workspaces\/wrk_krVZWGaJ\/projects",
"productions":"\/v1\/workspaces\/wrk_krVZWGaJ\/productions",
"subscription":"\/v1\/workspaces\/wrk_krVZWGaJ\/subscription",
"assets":"\/v1\/workspaces\/wrk_krVZWGaJ\/assets",
"descriptions":"\/v1\/workspaces\/wrk_krVZWGaJ\/descriptions",
"roles":"\/v1\/workspaces\/wrk_krVZWGaJ\/roles",
"registrations":"\/v1\/workspaces\/wrk_krVZWGaJ\/registrations",
"users":"\/v1\/workspaces\/wrk_krVZWGaJ\/users"
}
}
}
The model defines the links as async hasMany relationships, i.e. DS.attr('projects', {async: true}). When the workspace is loaded from the store, the linked projects aren't included. When you use {{#each workspace.projects}} or workspace.get('projects') anywhere else, ember-data will make a GET request to /v1/workspaces/wrk_krVZWGaJ/projects/, rather than the default route of /projects/. Neato, eh?
More details on the RESTAdapter findHasMany method.

ASP.NET Web API Authorization with AuthorizeAttribute

Using the new ASP.NET Web API beta. I can not seem to get the suggested method of authenticating users, to work. Where the suggested approach seems to be, to add the [Authorize] filter to the API controllers. For example:
[Authorize]
public IEnumerable<Item> Get()
{
return itemsService.GetItems();
}
This does not work as intended though. When requesting the resource, you get redirected to a login form. Which is not very suitable for a RESTful webapi.
How should I proceed with this? Will it work differently in future versions?, or should I fall back to implementing my own action filter?
Double check that you are using the System.Web.Http.AuthorizeAttribute and not the System.Web.Mvc.AuthorizeAttribute. This bit me before. I know the WebAPI team is trying to pull everything together so that it is familiar to MVC users, but I think somethings are needlessly confusing.
Set your authentication mode to None:
<authentication mode="None" />
None Specifies no authentication. Your application expects only anonymous users or the application provides its own authentication.
http://msdn.microsoft.com/en-us/library/532aee0e.aspx
Of course then you have to provide some sort of authentication via headers or tokens or something. You could also specify Windows and use the built in auth via headers.
If this site is mixed between API and actual pages that do need the Forms setting, then you will need to write your own handling.
All the attribute does is return an HttpUnauthorizedResult instance, the redirection is done outside of the attribute, so its not the problem, its your authentication provider.
Finally, I've found a solution at:
ASP.NET MVC 4 WebAPI authorization
This article shows how you can fix this issue.
You are being redirected to login page because forms authentication module does this automatically. To get rid of that behavior disable forms authentication as suggested by Paul.
If you want to use more REST friendly approach you should consider implementing HTTP authorization support.
Take a look at this blog post http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/
ASP.NET 5 Introduced the new Microsoft.AspNet.Authorization System which can secure both MVC and Web API controllers.
For more see my related answer here.
Update:
At that time 2 years ago it was Microsoft.AspNetCore.Authorization.
As #Chris Haines pointed out. now it resides on
Microsoft.AspNetCore.Authorization.
From .NET core 1.0 to 2.0 many namespaces have been moved i think.
And spread functionality between .net classic and core was obscure.
That's why Microsoft introduced the .net standard.
.net standard
Also, look at my answer for:
How to secure an ASP.NET Web API
There is a NuGet package I have created which you can use for convenience.
If you're using a Role, make sure you have it spelled correctly :
If your role is called 'Administrator' then this - for instance will not work :
[System.Web.Http.Authorize(Roles = "Administator")]
Neither will this :
[System.Web.Http.Authorize(Roles = "Administrators")]
Oops...
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Produces("application/json")]
[Route("api/[controller]")]
public class CitiesController : Controller
{
[HttpGet("[action]")]
public IActionResult Get(long cityId) => Ok(Mapper.Map<City, CityDTO>(director.UnitOfWork.Cities.Get(cityId)));
}
Use
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Filter with authentication type