I am creating a Laravel Application that supports mobile app and normal blade.
my Big problem of how to differentiate between return view and return json
there is a lot of opinion of how to organize the code I'd like to know what is the best practice for my case.
1- Create Different Controllers 1 for web other for mobile ( kills DRY concept )
2- Create 1 Controller for mobile return json and call it's functions from the web controller
3- Create service class contains the logic and create 2 controllers and inject an object in the constructore EX : [ Services/UserService.php ] [ UserController.php ] [ Api/UserController.php ]
which way should i Follow
Thanks in advance.
You can keep the code logic in the same controller#method and use wantsJson to determine Accept header and build an appropriate response
// build $responseData
if (Request::wantsJson()) {
return response()->json($responseData);
}
else {
return view('view')->with($responseData);
}
Related
I'm using Codeigniter. Basically what I want is to remove the Controller name (Home) from the url.
Those urls look like:
http://localhost/mechanicly/Home
http://localhost/mechanicly/Home/about
http://localhost/mechanicly/Home/contactus
now there are two ways I can remove the Home controller:
static definition of every url inside route:
$route['about'] = "Home/about";
$route['contactus'] = "Home/contactus";
I can use call backs in routes in Codeigniter:
$route['(.+)'] = function ( $param ) {
if( strpos( $param, "Admin" ) !== false ) {
echo $param;
return "Admin/".$param;
}
else{
echo $param;
return "Home/".$param;
}
};
this logic is much better as it is generic and I don't have to create new routes every time for new method inside the controller.
It is working fine for the client controller which is Home but I have another controller named as Admin and I want to redirect Admin requests to the Admin controller and Home request to the Home Controller.
Why does above code work fine for the Home controller but returns
not found
when I validate for the Admin controller?
I am using CI version 3.x
If you really want to get crazy, you could parse the methods from the controller file and programatically create the "static" approach.
Pseudo code here
$controller_file_contents = file_get_contents('path/to/controller.php');
$controller_methods = function_that_parses_methods_from_file($controller_file_contents);
foreach ($controller_methods as $controller_method) {
$route[$controller_method] = "Home/" . $controller_method;
}
How function_that_parses_methods_from_file works is probably gonna involve a regex, something like function \w+. If you go with this approach, try to keep the controller as small as possible by offloading as much logic as possible into models, which is often a good idea anyways. That way the performance impact in the router is as small as possible.
Alternatively, you may be able to parse the controller using get_class_methods if you can figure out how to load the controller into memory inside the router without conflicting when you need to load the controller using the router or causing too much performance issues.
Pretty goofy, but every method you create in that controller will automatically create a route.
you can create your menu(urlĀ“s) from db like
tbl_menu tbl_level
---------- -------------
id id
fk_level level
name dateUP
dateUP active
active
In your controllers you need to call the correct menu by session or wherever you want
then you can has this in your route.php
$route['(.+)'] = 'int_rout/routing/' . json_encode($1);
in your controller Int_rout.php
public function routing ( $param ) {
$routing = json_decode($param);
$routing = explode('/', $routing);
//$menu -> get menu from model
foreach($menu as $item){
if($routing[0] === $item->name){
//$level -> get level from model
$redirect = $level->level;
}
}
//the final redirect will be like
//admin/user or admin/user/12
//public/us
$params = ( empty($routing[1])) ? '' : '/' . $routing[1];
redirect($redirect . '/' . $routing[0] . $params, 'refresh');
}
Imagine a resource Post that you can perform CRUD on using a Restful API:
// in routes/api.php ...
GET /api/v1/posts API\V1\PostController#index
POST /api/v1/posts API\V1\PostController#store
GET /api/v1/posts/{post} API\V1\PostController#show
PATCH /api/v1/posts/{post} API\V1\PostController#update
// etc.
As you can see, each endpoint is handled by a controller action in Controllers\API\PostController, such as index, store, show, update, etc., as per Laravel conventions. Now, there's also a front-end dedicated controller, Controllers\PostController whose only responsibility is respond to one route /posts (in routes/web.php) and render a view:
public function index()
{
return view('posts.index');
}
In turn, this index.blade.php has many Vue components, one that GETs and lists all Posts from the API using Axios, one that POSTs and creates a new Post object, and others to update, delete, etc. Now, the problem is, how do I organize and name these components? Here's my shot:
Under assets/js/components, I created a posts folder, and added index.js, show.js, create.js, update.js, etc., mimicking the Blade views that I would have otherwise created in a traditional Laravel app;
Each file follows a standard...
module.exports = {
data() {
return { /* data here */ };
},
created() {
/* processing here */
}
}
...and is registered in assets/js/app.js following a <resource_name-action> pattern:
Vue.component('post-index', require('./components/posts/index.js'));
Lastly, components are used in index.blade.php as inline templates:
<post-index inline-template>
<!-- HTML markup here -->
</post-index>
Questions
Would this structure comply with recommended practices in Vue / Laravel?
Is it salable enough? Are component / file names semantic and/or standard?
Are there aspects that I neglected? Is it productive to have your views communicate with your API and DB in a single app? Or should they be split into two apps, one for front-end, another for back-end?
I am new to CodeIgniter, I want to build restful webservices using CodeIgniter. How can I post data to mysql and fetch from it back using REST services? I have gone through a web site 'tutplus', but it is explained there without mysql database.
Very simply, create some controllers, for example: user.php
At this controller write all necessary methods, exp: getUserInfo(), getUser(), getAge() and call these methods via URL.
To deal with this suggest:
https://ellislab.com/codeigniter/user-guide/general/controllers.html
https://ellislab.com/codeigniter/user-guide/general/routing.html
Actually on the project that i'm working on, we use RESTControllers, there's a project out there on github which extends codeigniter controller with all the REST capabilities:
https://github.com/chriskacerguis/codeigniter-restserver
All you need to do in your code it's include the file on the controller and extend that new controller:
require(APPPATH.'/libraries/REST_Controller.php');
class system extends REST_Controller {
}
You could also include the REST controller on the autoload libraries confinguration.
This library opens the 4 basic REST API as the GET, POST, PUT and DELETE
In your code the controller url should be declarated as this, so you would get a POST method on the index
public function index_post()
{
// ...just some code example
$this->response($book, 201); // Send an HTTP 201 Created
}
If you need a get on the index, you declare it as a GET method:
public function index_get()
{
// ...just some code example
$this->response($book, 201); // Send an HTTP 201 Created
}
I have to create an application with 5 types of roles.
So I started nesting my controllers
Controllers
administrator/establishments.php
supervisor/establishments.php
Views
administrator/establishments/index.php
supervisors/establishments/index.php
But I noticed that they have almost THE SAME CODE and the count of files will be huge!
I have been thinking in some ways to solve this
Controllers
establishments.php
and then ask:
if (Request::is('admin/*'))
{
Establishments::paginate(20);
}
if (Request::is('supervisor/*'))
{
Establishments::where_country(1)->paginate(20);
}
same for views.
Save role on session info, and create a menu to switch the var from one user to another
$role = Session::get('role');
if ($role == 'admin'))
{
Establishments::paginate(20);
}
if ($role == 'supervisor'))
{
Establishments::where_country(1)->paginate(20);
}
Any other ideas or suggestions?
What you could do is build a 'BaseCOntroller' wich has all the required logic in it.
On top of that you create the 5 other controllers - extend them on the BaseController.
Via the __construct() method you will pass the type so the BaseController knows what it has to do.
I'm trying to build a restful JSON api for my Symfony2 Application.
I'm using the http://jmsyst.com/libs/serializer JMS\Serializer Bundle to serialize my Entities to JSON.
I have this example Controller-Action:
public function getFarmerByNameAction(Request $request) {
$this->setLocale($request);
$name = $request->get("name");
$farmer = $this->getDoctrine()->getRepository("FarmerguideBackendBundle:Farmer")->findByName($name);
// Return json response
return new Response($this->jsonify($farmer));
}
Since I'm using this serializer very often (I know I should do something like a singleton or whatever, but currently I don't have the time for that, I was just playing with the framework) I've put the code inside a function which does the serializing.
private function jsonify($object) {
// Serialize to json
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new
JsonEncoder()));
$json = $serializer->serialize($object, 'json');
return $json;
}
My problem is the following:
This code is inside a BackendController, which does NOT contain any gui-specific information. So just a RESTful API.
In another Controller, let's say WebappController I have the code to access these backendfunctions and do some stuff with twig-files and render()-methods.
I want to access all these information via mobile over ajax (therefore I need this json return value)
What's the best-practice here? Is it better to say: Well if it's a ajax-call (check with if($request->isXmlHttpRequest())) , do jsonify right before returning the repsonse and if it's not return the entities (I need entities for twig-templates..) Or is there another approach?
Or is it even better to work with $request->getFormatType() and making the ajax call with contentType="application/json; charset=utf-8"
Here is how KnpBundles handles it https://github.com/KnpLabs/KnpBundles/blob/master/src/Knp/Bundle/KnpBundlesBundle/Controller/DeveloperController.php#L35
I guess you need to clearify what your intentions are. Because right now it seems as if your WebappController would just be a client to your Backendcontroller. Something like:
$result = file_get_contents('/path/to/backend/method/1/3');
You then simply go ahead and decode the json.
That is some additional overhead of course. If you want to get entities, I would suggest to create a Service for all your backend methods and return the entities there. You then simply call those methods from your BackendController and your WebappController. You then would only jsonify the entities in your BackendController and render the appropriate templates in your WebappController.