How to integrate Laravel with Vue.js in a Restful API application? - laravel

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?

Related

Laravel simple program

I am new to Laravel.
../laraone/public/ is working but cannot go further to create a simple aboutus page without the use of controller.
What is the pattern of URL to be used to get aboutus page.
Laravel uses MVC architecture. So to create a page you must go through A Controller and View (Model if you want to use DB and do data processing).
Soltuion # 1
You have to create a route first (Assuming Laravel 5.2):
// app/Http/routes.php in later version there is a separate folder for routes.
project_root/routes/web.php
Route::get('about-us','HomeController#aboutUs');
Controller :
// app/Http/Controllers/HomeController.php
public function aboutUs(){
return view('pages.aboutus'); //this will look for views/pages/aboutus.blade.php
}
View:
project_root/views/pages/aboutus.blade.php //put you html in this file
Solution # 2
Route:
// app/Http/routes.php in later version there is a separate folder for routes.
project_root/routes/web.php
Route::get('about-us', function () {
return view('pages.aboutus'); //this will look for views/pages/aboutus.blade.php
});
View:
project_root/views/pages/aboutus.blade.php //put you html in this file
Solution # 2 is not recommended but does the job. If you are new to laravel and learning it go for Solution # 1

RESTful service in CodeIgniter

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
}

Ember JS: How to load a second model based on data from a first

I have an Ember app that, rather than using Ember Data, uses our own custom AJAX data layer to talk to an API.
We're able to load two models at once using RSVP - one is a Project object via our API wrapper, the second is an object representing the logged in user. Both are passed into the controller and templates and work just fine.
But I have a need to load a second model, based on a value in the returned Project object.
Once I've loaded a model in my route like this...
App.ProjectUpdateRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('model', model);
},
model: function(params) {
return Ember.RSVP.hash({
// Load Project from API - /myapi/v1/Project/:ProjectID
Project : App.Project.create().findById(params.ProjectID),
// Load current user from local object
User : App.AuthUser,
});
},
});
...I have a Project object (or rather model.Project) with various properties including the ID of the User that owns the project.
Now I'd like to make a second API call to /myapi/v1/User/:UserID to get the User's details.
Everything I've tried - including adding further App.User.create().findById(UserID) calls into the route's setupController function and the controller - results in the correct API call, but it's asyncronous, so Ember carries on rendering the page and I can't show the result of the API call on the page.
So - how, and where in the Ember structure, do I load a second model based on data from the first? How can I get ember to wait for the resolved promise of this second AJAX call?
UPDATE
I've also tried using afterModel:function() which is almost what I need - it makes the second API call in the right place in the app flow, but I still need to add the result into my existing model array:
afterModel: function(model, tranistion, params) {
// Returns the promise but doesn't update 'model'
return Ember.RSVP.hash({
ProjectOwner : App.User.create().findById(model.Project.UserID)
});
}
Chain the promise, and Ember will take the final resultant (from the model hook)
model: function(params) {
return Ember.RSVP.hash({
// Load Project from API - /myapi/v1/Project/:ProjectID
Project : App.Project.create().findById(params.ProjectID),
// Load current user from local object
User : App.AuthUser,
}).then(function(results){
return App.User.create().findById(results.Project.UserID).then(function(user){
results.projectUser = user;
return results;
});
});
},

Maintaining Session through Angular.js

I am working a project using the AngularJS framework. I am pretty new to using this framework; in the past I have only worked with pure JavaScript and jQuery. The project is a kind of web designer application for a niche market.
As the user moves between pages while designing I want to maintain a session of all the changes they are making.
Now if the user signs in we load the session using data from the database. When the user clicks on save button we update the database with the session data. Someone told me that I can maintain session in Angular similar to backbone. Is this possible? If yes, can you please direct me to a tutorial that does not focus on directives or UI? If this is not possible are there other viable options?
Here is a kind of snippet for you:
app.factory('Session', function($http) {
var Session = {
data: {},
saveSession: function() { /* save session data to db */ },
updateSession: function() {
/* load data from db */
$http.get('session.json').then(function(r) { return Session.data = r.data;});
}
};
Session.updateSession();
return Session;
});
Here is Plunker example how you can use that:
http://plnkr.co/edit/Fg3uF4ukl5p88Z0AeQqU?p=preview
Because the answer is no longer valid with a more stable version of angular, I am posting a newer solution.
PHP Page: session.php
if (!isset($_SESSION))
{
session_start();
}
$_SESSION['variable'] = "hello world";
$sessions = array();
$sessions['variable'] = $_SESSION['variable'];
header('Content-Type: application/json');
echo json_encode($sessions);
Send back only the session variables you want in Angular not all of them don't want to expose more than what is needed.
JS All Together
var app = angular.module('StarterApp', []);
app.controller("AppCtrl", ['$rootScope', 'Session', function($rootScope, Session) {
Session.then(function(response){
$rootScope.session = response;
});
}]);
app.factory('Session', function($http) {
return $http.get('/session.php').then(function(result) {
return result.data;
});
});
Do a simple get to get sessions using a factory.
If you want to make it post to make the page not visible when you just go to it in the browser you can, I'm just simplifying it
Add the factory to the controller
I use rootScope because it is a session variable that I use throughout all my code.
HTML
Inside your html you can reference your session
<html ng-app="StarterApp">
<body ng-controller="AppCtrl">
{{ session.variable }}
</body>
You can also try to make service based on window.sessionStorage or window.localStorage to keep state information between page reloads. I use it in the web app which is partially made in AngularJS and page URL is changed in "the old way" for some parts of workflow. Web storage is supported even by IE8. Here is angular-webstorage for convenience.
You would use a service for that in Angular. A service is a function you register with Angular, and that functions job is to return an object which will live until the browser is closed/refreshed. So it's a good place to store state in, and to synchronize that state with the server asynchronously as that state changes.
Typically for a use case which involves a sequence of pages and in the final stage or page we post the data to the server. In this scenario we need to maintain the state. In the below snippet we maintain the state on the client side
As mentioned in the above post. The session is created using the factory recipe.
Client side session can be maintained using the value provider recipe as well.
Please refer to my post for the complete details.
session-tracking-in-angularjs
Let's take an example of a shopping cart which we need to maintain across various pages / angularjs controller.
In typical shopping cart we buy products on various product / category pages and keep updating the cart. Here are the steps.
Here we create the custom injectable service having a cart inside using the "value provider recipe".
'use strict';
function Cart() {
return {
'cartId': '',
'cartItem': []
};
}
// custom service maintains the cart along with its behavior to clear itself , create new , delete Item or update cart
app.value('sessionService', {
cart: new Cart(),
clear: function () {
this.cart = new Cart();
// mechanism to create the cart id
this.cart.cartId = 1;
},
save: function (session) {
this.cart = session.cart;
},
updateCart: function (productId, productQty) {
this.cart.cartItem.push({
'productId': productId,
'productQty': productQty
});
},
//deleteItem and other cart operations function goes here...
});

Backbone JS and CodeIgniter REST Server

I have a standard CI web app, but I've decided to get the chaotic javascript in order using backbone. I had a whole pile of serialized forms/jQuery AJAX requests to various controller methods: authenticate, change_password, register_member, request_new_password, etc.., and don't quite understand how REST works instead. I'm using Phil Sturgeon's REST library for CI https://github.com/philsturgeon/codeigniter-restserver
Should every backbone model have a different api url? And what am I supposed to actually call the controller methods?
<?php
require(APPPATH.'/libraries/REST_Controller.php');
class RestApi extends REST_Controller
{
function get()
{
But it just 404s.
I just don't get how to replace the routing to fifty of my old methods based on a handful of HTTP methods. Does the name of the backbone model need to match something on the server side?
You have to name your functions index_HTTPMETHOD. In your example it would be:
class RestApi extends REST_Controller {
// this will handle GET http://.../RestApi
function index_get() {
}
// additionally this will handle POST http://.../RestApi
function index_post() {
}
// and so forth
// if you want to POST to http://.../RestApi/somefunc
function somefunc_post() {
}
}
the url-attribute of the model should match the server-side 'url' which returns the JSON that will make up the model's attributes. Backbone.js has default functionality to this, which is to match the model's collection url with it's id attribute. The collection url requirement can be foregone by overriding the urlRoot -function, in order to operate model's outside of collections.
If you want to be independent of the id -attribute as well, you sould override the url -attribute/function to provide your own url that matches to the model on the server, like this:
url: 'path/to/my/model'
or
url: function() { // Define the url as a function of some model properties
var path = this.model_root + '/' + 'some_other_url_fragment/' + this.chosen_model_identifier;
return path;
}

Resources