I need to send a push message from Urban Airship. To do this I have to send an API request from CakePHP.
My question: where should i put the code for the API request in CakePHP? In the model or in the controller? Where is the correct place for this?
I follow Neil Crookes' idea of keeping the logic in the datasource. An API is really just a datasource, after all. Then, models are introduced as the various endpoints the API has. For example, I have a Stripe plugin that follows this model. A StripeCustomer model then has a $path variable that the datasource uses as the endpoint.
This model has several benefits:
API calls are integrated with the ORM - so they look like regular model finds and saves
You can utilize built in validation, callbacks, behaviors, etc.
Very DRY and therefore easy to debug and test
Related
I have an MVC PHP web application that needs to call a REST API. I'm unclear on whether I should be calling the API from my controller or from the model? Looking at various resources I'm getting mixed information. I assume it should be from the Model since all I'm doing is dealing with data and passing that up to the controller correct?
Some more details to clarify. I do have full control over the REST API which I'm in the process of building and is in PHP as well. The API however will also be leveraged by an iOS and Android companion app built by my team and a few other apps running on proprietary devices.
The original plan was that the web app was not going to leverage the API and just go straight to the DB to cut out any overhead, but several debates later and I'm leaning toward using the API.
I'd call from the model if the REST resource is a representation of the model, or if you're going to need this functionality across multiple controllers.
Call from the controller if it is not 100% specific to the model representation, or if it is only important to the controller/view you're working with.
You should call the web API from the Controller. The Model is how the data is passed from the Controller to the View. The Model should only have data and no business logic.
When you get the response from the web API, the data should be put into the Model and passed to the View.
The Model, the View and the Controller make up the MVC pattern. The Controller is responsible for putting the data in to the Model, which it passes to the View. The View takes the Model and displays the data, as it has been told to. There is no Business Logic in either the Model or the View.
Ideally, you would put your API code into a class library, that the controller uses. This allows you to separate the business logic out of the website and into a separate component.
Currently building an API that pulls data from another API.
I'm just a little unsure about how I should represent some data considering the whole skinny/fat model/controller argument and I haven't been able to find a clear answer so I was hoping for a discussion on this here.
As Models represent interactions with data it feels like my calls be mapped into a model using something like Fractal or Jenssengers "Laravel Model".
As currently I have actions in my controller that send send requests, but it feels like this is a bit too much responsibility for a controller.
So I just wanted some opinions on where I should place this logic in regards to a Laravel project!
Thanks
EDIT:
From further research it looks like the repository design pattern may be a possible solution!
Repositories Simplified
Using Repository Pattern In Laravel 5
Neither method is particularly a great solution. Really, a Controller is responsible for handling the HTTP requests and your models are representations of your business domain. So where does third-party data fit into this?
Well, the data itself should probably be represented by a model. However, the method of getting the data from the third party provider should really be delegated to a service provider that you can then easily switch out to work with different apis and thus decoupling yourself from a single provider (easiest example would be payment gateways, having all of your logic hard coded in your Controller for a Paypal integration would make it extremely difficult to then later add a second payment option).
Take the following example; let's say you have an application that provides a user with the latest results for their favourite football teams.
Your application could have the following endpoints:
/team/{team}/players
/team/{team}/fixtures
/team/{team}/results
These could map to the following controller methods:
PlayerController#getPlayersInTeam($team);
FixturesController#getFixturesForTeam($team);
ResultsController#getLatestResultsForTeam($team);
Notice there are three different controllers, rather than one single controller. This way you can assign a controller to the type of model you're expecting to return to the user.
Now obviously, you shouldn't do your API calls within each controller. But, why would you then do it within your model? The term 'Skinny controllers, fat models' is such an anti-pattern that it really does a lot more harm than good.
Why not use a service that is solely responsible for getting data from the API for your models?
interface FootballTeamData
{
public function getPlayersInTeam(Team $team);
public function getTeamFixtures(Team $team);
public function getTeamResults(Team $team);
}
Now, you can implement this contract and easily switch the way that you get your data from third parties without having to touch your models - which is your business domain, and therefore shouldn't be so highly coupled with the third party API.
You're also now benefiting from skinny controllers, and skinny models. There's no reason why a class can't exist that has just a few lines of code, neither should be fat.
Good luck!
I'm building a small TV Show library in laravel. I want to include an API as well for possible future expansion. When I started I had 2 controllers for what should have been a single controller: API controller and the web frontend controller. They both handled the same logic. That's obviously not good practice since that leads to duplicate code.
How would I make my application API centric? I was thinking of having an API controller which handles all the logic and returns a JSON object and a regular controller for the frontend which simply takes the JSON object returned by the API controller and passes it to a view (after, if any, processing). If that's the way to go, how would I retrieve said object? A GET request to my own server?
If you are developing API, than it should be on a separate server to take off load form main web server.
If it is on a same server, why would you send a request to it as you can develop a class that can act as API and call it inside your web controllers.
Later on when you decide to have separate server, just wrap API contoller around that class.
<?php
$myApi = new MyApi();
$myApi->setParmas( $paramsArray );
$myApi->doLogic();
echo $myApi->asJson();
// or make API class that can handle one liner
echo MyApi::factory($_GET)->doLogic()->toJson();
?>
Make your Laravel application an API endpoint and use a frontend framework or some frontend routing and templating libraries to handle the client-side.
Name space the api with /api and versions i.e. /api/v1
This allows you to easily develop with many different technologies and not have to rewrite your backend, as it is just an API endpoint.
It can then serve your webapp, an iOS app, an Android app, etc. because all it does is handle data, validation, requests, security, etc.
You can use repositories to get required data, then you may pass it to a View to make a webpage, or just print the JSON, for the API, this way you can prevent duplicate code.
Route::get('/latest', function () {
return View::make('latest', Movie::latest());
}
Route::get('/api/latest', function () {
return json_encode(Movie::latest());
}
Check this video for more info about repositories in Laravel: http://vimeo.com/53029232
In larval 5.3 you may want to consider using larval passport which provides a really nice way to consume your own api's from the front end without needing to worry too much about the authentication https://laravel.com/docs/5.3/passport#consuming-your-api-with-javascript
There is also a nice video on this on laracasts https://laracasts.com/series/whats-new-in-laravel-5-3/episodes/13
I have an existing app that was built on the Yii Framework for managing wine cellars. I used the standard Gii utility to create the initial CRUD controllers/models/views. I've significantly modified the code to meet my needs for navigation, look & feel and functionality. I'm now beginning the design for a companion mobile (android) app that will need to consume and create some of the data (get a list of wines in my cellar - GET, add a new wine to the cellar - POST) that can be used while out shopping/wine-tasting. I don't intend to expose all the models/controller options as web services, only a specific set of functions.
My question is really a design issue. Should I add the API methods to the existing CRUD controllers or should I create a new "API Controller" for each of the models (or a single apiController is another option I've seen)? My thinking is separate API controllers. This would allow me to update/deploy API specific changes more easily and to logically compartmentalize that interface. This API will need to be authenticated and I will probably implement OAuth in a future release.
BTW, I've looked at the RESTFullYii extension and I haven't been able to grok exactly how it works. I'd really love to see a working example app not just code snippets.
I suggest you to create a new controller. For example ApiController. You put all your actions such as actionAddWine. So you can call this action like:
http://example.com/index.php?r=api/addWine
The advantage of doing this, is that you have all your models, and you just need to interact with your modes via REST. In order to create a simple REST api you can check the following document which is really simple explained.
How-To: Create a REST API
If you do like the mentioned article, You can send the response to client simply using _sendResponse() method.
Another thing is to do authentications and similar things which can is readily attainable using your controller's init() method.
Another way is to create a module for your application. If you want to completely divide your API from your other codes you can create a module. You can create modules with GII. The advantage of module is that you can separate your sections. For example your actions will be:
http://example.com/index.php?r=api/wine/add
in above url you are calling an action in api module, and wine controller which its name is add.
Note that you can use your models in module by importing them.
Yes, go for separate controllers. You may even want to set up a separate application that shares some of your apps models and config but also allows for a more separate feel.
Also with planning how you will version your Api, as it is likely to need to change down the road while still needing to support your older Android app
I am developing RESTful with php. Currently I have started coding with MVC design pattern. In which the view files are acting as an interface. An interface which isn't showing any graphical UI but it has all the request handling logic.
Now, my question is the way I am coding is correct or there is a better way to create RESTful api in php?
My inspiration is based on JavaEE application model. In which we have Entity classes as model, Java beans as controllers and Remote Interface is the the list of method which gets called from client (kind of a view).
Am I on right track?
A good example for building a RESTful API in a PHP based MVC framework can be found at http://www.chrisdanielson.com/2009/09/02/creating-a-php-rest-api-using-the-zend-framework/.
This example extends a class in Zend Framework called the Zend_Rest_Controller which simplifies this process. You can have a look at the source code to see how they do it and if it gives you an ideas on how to make your own implementation.
To answer your question though, you should have controllers acting as the interface. So if you send a POST request to myapp.com/comment (where comment is the controller), it knows you are trying to add a new comment. If you send a GET request to the same URL, it knows you want all of the comments, and if you send a GET request to myapp.com/comment/4 it knows you want to get the comment with ID 4. Your views should have nothing to do with the internal functionality of your API.
You can use any existing RESTful PHP MVC framework, like Yii or Kohana both are very light and natively support RESTful applications.
For your existing application, MVC model states that all the requests and logic handling should be done by the Controllers not the views. Things are usually done in one of two ways here:
(1) Controller has a special method to respond to each type of requests and acts differently As seen in RubyOnRails (mainly at the end of each controller action)
respond_to do |format|
format.html
format.xml { render :xml => #events}
format.json { render :json => #events}
end
(2) Controller detects the current requested format and changes that entire theme/layout to, say, a JSON theme (All layouts/views receive the same data). This is my current implementation and it goes like:
$format is any of [html,json,xml] (detected from url suffix)
$controller->layout = "$format";
$controller->render($viewFile, $object);
view file in HTML Layout
<div id='model>
<h1><?=$object->title?></h1>
<p><?=$object->description?></p>
</div>
View file in JSON layout
echo json_encode($object);
View file in XML layout
/** Loop and build XML tree */
I did a bunch of webinars on API Facade Design Patterns. Hope you will find the concepts useful irrespective of the underlying technology you use to implement it. Please can find it here
http://youtu.be/n8B-K3iJ7b4
http://youtu.be/MRxTP-rQ-S8
http://youtu.be/aJBhVm4BbCI
Apigility is a Zend Framework 2 based project designed soley for the purpose of creating REST and RPC services.
https://apigility.org/
Out of the box you're given an easy way to get started with MySQL and OAuth2 for authentication.