One place for hosting & domains

      Route

      Cleaner Laravel Controllers with Route Model Binding


      Introduction

      Laravel as a framework either for building websites or a container to build APIs (lumen) has evolved as a developer’s framework of choice. Laravel comes with a lot of growing features – take for example Laravel’s events. Events in Laravel used to be a simple pub-sub library, but now Laravel events can broadcast all the way to the client and allows us to create real-time apps.

      But that’s beside the point, today’s celebrity is Laravel’s route model binding.

      What is Route Model Binding

      Route model binding in Laravel provides a mechanism to inject a model instance into your routes. Still not clear on the meaning, here is an example. Say we want to get a post from the database, we could do something like this:

      ...
      // the route parameter is the id of the post
      // for example http://example.com/posts/53
      Route::get('posts/{id}', function ($id) {
      
        // we have to find the post using the $id
        $post = Post::find($id);
      
        // if there is no post, 404
        if (!$post) return abort(404);
      
        // return the view and the post
        return view('post.show', compact('post'));
      });
      ...
      

      We could further go on to simplify this method into

      ...
      // the route parameter is the id of the post
      // for example http://awesome.dev/posts/53
      Route::get('posts/{id}', function ($id) {
      
        // find the post or 404 if not found
        $post = Post::findOrFail($id);
      
        // return the view and the post
        return view('post.show', compact('post'));
      });
      ...
      

      But route model binding helps us get rid of extra keystrokes by simplifying both instances above into

      ...
      // by using $post, we can inject the Post object
      Route::get('posts/{post}', function ($post) {
      
        // we now have access to the $post object! no code necessary
      
        // return the view and the post
        return view('post.show', compact('post'));
      });
      ...
      

      This is made possible by telling Laravel to inject a Post model into any route controller that has a {post} parameter attached to it.

      Laravel currently supports two types of route model bindings. We have:

      • Implicit model binding
      • explicit model binding

      Note: The example of route model binding listed above is explicit.

      Implicit Model Binding

      While we’ve seen explicit model binding, here’s an example of implicit model binding now:

      Route::get('posts/{post}', function (AppPost $post) {
        // be awesome. enjoy having the $post object
      });
      

      Laravel is smart enough to know that since a Post model is being injected into the controller closure, it should get the id parameter from the route and get the details for the user.

      Accessing a post will still be done using http://awesome.example.com/posts/24.

      Changing the Model’s Route Key

      If you would like the implicit model binding to use a database column other than id when retrieving models, you may override the getRouteKeyName method on your Eloquent model.

      For instance, if we wanted to use the slug instead of the id, we could do the following:

      class Post extends Model {
        public function getRouteKeyName() {
          return 'slug';
        }
      }
      

      Then we could access our route using http://awesome.example.com/posts/my-post-slug instead of http://awesome.example.com/posts/24.

      Explicit Model Binding

      Just like the name implies, you have to explicitly tell Laravel you want it to bind a url parameter to a particular model. There are two ways to do this, we could bind a parameter to a model using the provided Route facade or carry out this binding in app/Providers/RouteServiceProvider.php (I prefer this method).

      Using the Route Facade

      Using the Route facade to bind a parameter to a model, we can do something like this:

      Route::bind('post', 'AppPost');
      

      We could also give our binding more meaning, for example, what if we want a post only if is a draft? For that, we could change the second parameter of the Route::bind to a closure which takes the route parameter as its value.

      Route::bind('post', function ($value) {
        return AppPost::find($value)->where('status', '=', 'published')->first();
      });
      

      Using the RouteServiceProvider

      The only difference between using the Route facade and RouteServiceProvider class is that – registering your bindings is done in the boot method of the RouteServiceProvider class (location is app/Providers directory) and the bind method is called on the $router object injected into the method. Quick example

      public function boot(Router $router)
      {
        parent::boot($router);
      
        $router->bind('post', function ($value) {
          return AppPost::find($value)->where('status', '=', 'published')->first();
        });
      }
      

      Custom Exceptions for Route Model Binding

      I build a lot of APIs, so custom exceptions for route model bindings are actually more useful for people like me. Laravel provides an easy way for us to do this. Still in the boot method of the RouteServiceProvider class, call the model method on the $router object.

      The model method takes three arguments, the arguments are similar to that of the bind method, with a new addition the third argument which is a closure that throws the new exception.

      $router->model($routeParameter, $modelToBind, function () {
        throw new NotFoundHTTPException;
      });
      

      Conclusion

      You can read more about route model binding in the documentation.

      Hopefully this small, but neat feature can save you a few lines of code in your projects and make your controllers that much cleaner.



      Source link

      Get Laravel Route Parameters in Middleware


      Today we’ll be talking about how to use route parameters in middleware, a task that may come up in your workflow.

      What is Middleware?

      A middleware simply wraps an application’s request. Think of it this way, when a request is made to your application, there’s code that handles the request, but if you want something to occur before or after the code that handles the request is run, you would put in a middleware.

      Laravel comes with a few inbuilt middlewares for maintenance, authentication and CSRF protection, which are all found in the app/Http/Middleware directory inside a laravel project folder.

      Laravel Route Parameters

      Laravel routes are located in the app/Http/routes.php file. A route usually has the URL path, and a handler function callback, which is usually a function written in a certain controller.

      // Inline function to handle the route
      Route::get('/', function () {
          return view('welcome');
      });
      
      // Controller function to handle the route
      Route::get('/profile', 'ProfileController@index');
      

      A parameter provided in the route is usually annotated with curly braces. For instance, to pass in a name parameter to a route, it would look like this.

      Route::get('/params/{name}', function ($name) {
          return $name
      });
      

      By convention, the Controller function accepts parameters based on the parameters provided.

      Accessing Route Parameters

      Accessing parameters in a middleware however is not that direct. First let’s create a middleware called DumpMiddleware that dumps the parameters provided in the route.

      php artisan make:middleware DumpMiddleware
      

      The file app/Http/Middlware/DumpMiddleware.php is created.

      Method 1: $request->route('parameter_name')

      We can access route parameters in two ways. One way is by using $request->route('parameter_name')., where parameter_name refers to what we called the parameter in the route. In the handle method within the DumpMiddleware class created in the app/Http/Middleware/DumpMiddleware.php file.

      public function handle($request, Closure $next)
      {   
          dd($request->route('parameter_name'));
          return $next($request);
      }
      

      To see the middleware in action, let’s add it to the route. Quickly create the route we showed above and add the middleware in the app/Http/routes.php file.

      Route::get('/params/{name}', [
          'middleware' => 'AppHttpMiddlewareDumpMiddleware',
           function () {
              return view('welcome');
      }]);
      

      We need the full namespace of the middleware, because we have not made Laravel aware of our new middleware. To do this we add it in the AppHttpKernel.php file, as part of the $routeMiddleware class property.

      protected $routeMiddleware = [
          // Middlewares commented out for brevity
          'DumpMiddleware' => AppHttpMiddlewareDumpMiddleware::class,
      ];
      

      You can then update the middleware in the route to be 'middleware' => 'DumpMiddleware',.

      Run php artisan serve on your terminal and open http://localhost:8000/params/scotch. You should see scotch dumped in the browser.

      Method 2: $request->route()->paremeters()

      The other way to access the Route parameters in the middlware involves gettting all the parameters. Imagine you had a route like this /params/{id}/{category}/{name}. All the route params are usually saved in an array, which in a middleware is accessible through $request->route()->parameters(). If we update our route to the above route,

      Route::get('/params/{id}/{category}/{name}', [
          'middleware' => DumpMiddleware',
           function () {
              return view('welcome');
      }]);
      

      And update the middleware’s handle method to,

      public function handle($request, Closure $next)
      {   
          dd($request->route()->parameters());
          return $next($request);
      }
      

      Going to http://localhost:8000/params/23/scotch/school should dump the parametes in your browser as an array, with the parameter names as the keys, and what was passed as values.

      Why Access Route Parameters in Middleware?

      A sample usage for accessing route parameters in middleware is when a given route performs different actions. Say for instance you have a route that returns user’s profiles, /{username}. To go to Scotch’s profile for instance, one would go to http://localhost:8000/scotch.

      This app, however, may have some routes that do not necessarily belong to profiles. Like faq, or support, or help. In such a scenario, it is usually recommended to have these routes defined before the route that looks for a profile.

      app/http/routes.php

      Route::get('/faq', function() {
          return view('faq');
      });
      Route::get('/help', function() {
          return view('help');
      });
      Route::get('/support', function() {
          return view('support');
      });
      
      // Route that handles profile comes last
      Route::get('/{username}', function() {
          return view('profile');
      });
      

      With middleware however, all we need to do is check if a value is in a defined array and redirect.

      app/Http/routes.php

      Route::get('/{username}',  [
           'middleware' => 'ProfileMiddleware',
           function () {
              return view('welcome');
      }]);
      

      Then in the profile middleware, we add this in the handle function.

      <?php
      
      namespace AppHttpMiddleware;
      
      use Closure;
      
      // Add Response namespace
      use IlluminateHttpResponse;
      
      class ProfileMiddleware
      {
          public function handle($request, Closure $next)
          {   
              $routes = ["faq", "support", "help"];
              $route = $request->route('username');
      
          // Redirect to custom page if it doesn't relate to a profile
              if (in_array($route, $routes)) {
                  return new Response(view($route));
              }
      
              return $next($request);
          }
      }
      

      We simply check if the parameter is in a given array, and return a view based on that. In case we have any other keywords that are not neccesarrily profiles, all we need to do is add them to this array. Cleaner, right?



      Source link

      Network Route Optimization Made Easy with Performance IP (Demo)


      Latency. It’s the mortal enemy of virtual dragon slayers, the bane of digital advertisers and the adversary of online retailers. Every end user has experienced the negative effects of latency, and even though they don’t always understand the intricacies of routing traffic through a global network, their responses to that latency can have a lasting impact on the companies whose networks aren’t functioning at peak performance.

      Consider this: More than seven in 10 online gamers will play a lagging game for less than 10 minutes before quitting. As much as 78 percent of end users will go to a competitor’s site due to poor performance. And a one second delay can cause an 11 percent drop in page views, a seven percent drop in conversions and a 16 percent drop in customer satisfaction. For online merchants, even the big boys like Amazon, each one-second delay in page load time can lead to losses of $1.6 billion annually.

      Milliseconds matter. Anyone focused on network optimization knows this. But did you know that Border Gateway Protocol (BGP) only routes traffic through the best path around 18 percent of the time? The lowest number of hops does not equate to the fastest route. And yet seeking a path with the least hops is the default.

      What if there was a better way to find the lowest latency route to reach your end users?

      Find the Fastest Network Route with Performance IP®

      With INAP, finding the lowest latency route doesn’t require you to lift a finger. Customers in our data centers are connected to our robust global network and proprietary route optimization engine. Performance IP® enhances BGP by assessing the best-performing routes in real time.

      This technology makes a daily average of nearly 500 million optimization across our global network to automatically put your outbound traffic on the best-performing route. And with the meshed infrastructure of Tier 1 ISPs and our global network, you don’t have to choose between reliability, connectivity and speed. You can download the data sheet on Performance IP®here.

      “In online games, lag kills,” said Todd Harris, COO of Hi-Rez Studios, an INAP customer. “To deliver the best experience, we have to make sure that gamers are able to play on the best network while using the most efficient route. INAP delivers all of that.”

      Skeptical about what Performance IP® can do for you? Let’s run a destination test. Below, we’ll take you through the test step by step so you can get the most out of the demo when you try it for yourself.

      Breaking Down the Performance IP® Demo

      You can access the demo from the INAP homepage or the Performance IP® page. Get started by entering your website URL or any destination IP. We’ll use ca.gov for our test purposes.

      Performance IP Homepage

      Next, choose your source location. The locations in the drop-down menu represent INAP’s data centers and network points of presence where you can take advantage of the Performance IP® service. Each market has a different blend of Tier 1 ISPs. Performance IP® measures all carrier routes out of the data center and optimizes your traffic on the fastest route to your target address.

      Here, we’re running the test out of our Atlanta flagship data center, but you can test out all of our markets with the demo. We’ll run the route optimization test to our sample website, which is located in California. Once you have all your information entered, click “Run Destination Test.”

      Destination test
      Click to view full-size image.

      As you can see from the result of our test above, the shortest distance is not the lowest latency path. Each Greek letter on the chart represents an automonous system (AS). The Performance IP® service looked at seven carriers in this scenario and was able to optimize the route so that our traffic gets to its destination 21.50 percent faster—16.017 ms faster—than the slowest carrier.

      Destination Test Summary
      Click to view full-size image.

      In the traceroute chart above, we can study the latency for the each carrier more closely. Although in this scenario the best perfroming carrier passed though three automous systems while all of the other carriers passed through only two, it was still the fastest. Note that default BGP protocol would have sent us through any of the other carriers, including the slowest route through Carrier 3.

      Once you’ve had time to adequately study the outcome of the test, click “Continue” to see carrier performance over the last month. This chart measures the percentage of carrier prefixes originating from our Atlanta POP that had the best and worst performing routes for any given day of the month. While individual carrier performance can vary radically, if you’re a Performance IP® customer this won’t be a concern for you. Since the engine measures network paths millions of times a day, Performance IP® sends outbound traffic along the lowest latency path virtually 100 percent of the time.

      The final tab of the demo allows you to study our product line-up and open a chat to get a quote. Performance IP® is available for INAP colocation customers and is included with INAP Cloud products. If you’re not interested in these infrastructure solutions, you can still purchase Performance IP® from one of our data centers and connect it to your environment.

      Run the test for yourself, or chat with us now to get a quote.

      Explore the INAP Performance IP® Demo.

      LEARN MORE

      Laura Vietmeyer


      READ MORE



      Source link