RSS

Presentation on Building an API with Yii2 at PHP Melbourne

0 Comments | This entry was posted on Mar 22 2016

Last week I made a presentation at the Melbourne PHP usergroup phpMelb. The presentation was a live demonstration on how someone would go about creating an API with Yii2 from a clean install. I went through the steps of creating a migration and building the model with Gii. Then, following the Yii2 guide on how to turn a controller into a RESTful API controller. The steps are very straight forward and very quick.

I discussed using Chrome extension Postman to create and submit the payload and to view results. I showed how to add behaviours to the models and controllers but could only touch on authentication because of time constraints. I also demonstrated that with the advanced template you can also have a backend which I built again with Gii to show how easy it is to create a web based admin part of the API/site.

You can view the presentation here: https://doublehops.com/presentations/yii2-api-presentation.

Building RESTful APIs with Yii2

0 Comments | This entry was posted on Sep 21 2015

I have been building an API with Yii2 for the last four months and and I’m really enjoying it. The developers of Yii have done a tremendous job putting together a framework that makes building applications both fun and fast. The API is to be used by iOS and Android apps as well as a web app (Angular JS) to facilitate phone calls and messages, among other things.

Many of Yii’s strengths come from the clever and well thought-out design that makes common tasks incredibly easy to implement and more complex tasks easy to build whilst keeping the code and structure of your application clean. Some of my favourite attributes to see are:

RESTful services

Building a RESTful service is incredibly quick to build by calling the inbuilt scaffolding tool. It will read the database table to build the model, and also views if you’re building a traditional website. Then with just a few changes in the controller you can start creating, reading, updating and deleting records through your browser.

Behaviours

Attaching a behaviour to a component or controller is similar to extending a class but gives you more control and can act on events. Yii2 has a collection of behaviours that are built in but allows you to create your own. Two built-in behaviors that I’m using are Authenticator and CORS.

Authenticator behaviour: This behaviour allows you to easily implement common authentication models such as HTTP Basic Auth and OAuth. But I was able to add a custom authentication module to the auth behaviour to meet our unique rrequirements.

CORS behaviour: CORS (Cross Origin Resource Sharing) is a standard that allows browsers to make Javascript requests to servers that the Javascript files themselves weren’t server from. This is generally not possible due to security issues. CORS can be quite complicated and can cause major headaches but Yii2 allows you to simply include the behaviour to a controller and the API will respond with the required headers to each CORS request from the browser.

Custom authentication

Yii2 has a great solution for Authentication and has the common ones, such as OAuth and Basic Http Auth built in. But it also quite simple to add your own authentication if need be. The requirements for us was to allow each user to connect to the API with multiple devices. Therefore each device is required to send its individual token for each request made to the API. Yii2 makes this quite trivial.

Testing

Yii makes it easy to use use test databases and environment variables which makes testing easy. My solution was to setup an alias domain (env.myapi.test) for each environment. When Yii receives a request on a domain ending with .test it will use test variables and database to run my tests and not pollute the dev or prod data with test data. Every API endpoint is tested and it’s very reassuring watching the tests that you have not broken any endpoints when new features are added.

Growing pains building RESTful APIs with Yii2

0 Comments | This entry was posted on Feb 26 2015

Update:

The issues discussed in this post were easily resolved and surfaced due to my unfamiliarity with the new version of Yii. Issue one fixed with one line of code. When JSON output is required you can set this by adding a new line into the controller action:

\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

Issue two is also easily resolved by creating an actions method in your controller and unsetting the default action that you need.

As most things in software development, the things you’re looking for are a lot easier to find when you have a better idea of what you’re looking for.

Original post:

I have begun playing with Yii2 to build RESTful APIs with the intention of creating backends for single-page websites and mobile apps. Although I am excited at how well Yii2 applications are built I am seeing issues and bugs when following documentation and examples. Unfortunately for me it doesn’t seem that many people are building RESTful apps with Yii2 at this time to ask questions from. Here are some issues that I’m experiencing.

Issue 1

When extending a controller from the RESTful ActiveController the behavior method is no longer available. It triggers an exception with the error:

Response content must not be an array

Is this due to a bug that’s been introduced?

Issue 2

When extending a controller from RESTful ActiveController, the normal action methods are no longer used or can be modified. There doesn’t seem to be a way to add additional functionality because of this such as pagination rules. How would I go about hooking into these actions?

Answers

I feel that the documentation I’m reading is from earlier iterations of Yii2 and not valid for the latest version. I would love to hear from anyone who can shed some light on these issues.

Example I’m referring to

http://www.yiiframework.com/doc-2.0/guide-rest-quick-start.html

Setting up development environments for Yii2 with Vagrant and Ansible

0 Comments | This entry was posted on Feb 18 2015

In an effort to streamline all work and learning that I do I have put together an Ansible script that will build a web server with Yii2 advanced application template framework ready to start development with the newly released Yii2 PHP framework.

After Vagrant is used to create the virtual machine with Debian 7, Ansible is called to provision the server with PHP5.5, MariaDB and Nginx. It will then setup to virtual host for Yii2 framework with both frontend and backend configuation.

The scripts are available on Github for anyone who wants to have a try with Yii2.

Crypto-Currency Market Watcher Built with Yii2

0 Comments | This entry was posted on Feb 02 2015

Some time ago I wanted to sink my teeth into Yii2. The completely rewritten framework built with PHP. To do so I decided to build a crypto-currency market watcher. My idea was to build a site that would download all market data at regular intervals from different exchanges and record the values, which could then be graphed and sorted in an effort to watch near real-time market trends.

It proved to be both fun and challenging. What I enjoyed a lot was using Composer to install Yii and third-party packages required to meet some tasks. Quite a lot changed with the new version of Yii. One of those is the way that you create and use components. But once you’ve got it, it makes sense with the new format.

At the time I built components for markets at Cryptsy and Mintpal but it is rather easy to add new crypto exchanges. If you use a marketplace that offer an API then you can most likely add it to Coinhawk.

It really is a pleasure to work with Yii2. If anyone would like to see the code and even run the site themselves, I have made the repo public on Github: https://github.com/doublehops/coinhawk

The repo includes a vagrant machine provisioned with Ansible so it’s incredibly easy for a developer to get started. I would love to hear some feedback

Yii2: Second Generation Yii

0 Comments | This entry was posted on Jul 01 2014

I found enough time recently to finally look into Yii2. I decided that a good test project would be to build a crypto currency exchange tracker. It would download latest prices of all markets from both Cryptsy and Mintpal and then display the data in charts so I could quickly scan trends of all currencies.

Yii2 and it’s dependencies can be installed and managed through Composer which I enjoy. It prevents you from needing to keep any third party packages in version control and makes installs, upgrades and deployments easier. The Yii2 documentation is again great and the community is already solid. Any questions I had that were Yii2 specific were answered on the forum in good time. Some things are different and migrating projects from Yii 1.x to 2.x will take a lot of work. Yii2 uses namespaces and this means namespaces need to be declared at the top of views and other files that wasn’t previously necessary. Getting instances of records is slightly different and was changed several times during Yii2’s evolution. However this is stable now.

Many things are still the same. Migrations, scaffolding, commands and nearly everything else is the same. In my opinion, Yii2 is still the best PHP framework and I can’t wait to start a production project with it. Yii2 is still beta but the code base has mostly settled with only bug fixes remaining. My next task is to incorporate AngularJS into my Yii projects.

Setting Up Development Environments With Vagrant and Ansible

0 Comments | This entry was posted on Feb 19 2014

One of the reasons I love running Linux on my main laptop/workstations is that I have an ideal environment to develop web projects. However there’s been many developments in software that moves away from this model which I have grown to love, and that is running your dev environments in virtual machines.

Instead of running Apache (or Nginx), MySQL and PHP natively on my dev machine, I have found it’s now easier to setup and run dev environments in virtual machines that are configured specifically for a given project, which can be automated through server management scripts. Initially this sounds like additional work, and it is but it has several advantages:

  • Custom environments for each project
  • Easily deployable for other developers in your team
  • No knowledge required for other team members.
  • Scripts can be reused for staging and development environments.

What are Vagrant and Ansible:

Vagrant is software that allows you to easily build reproducible development environments for various operating systems. It runs on top of other virtual machine platforms such as Virtualbox but, among other things, creates a sync drive that is accessible to your local file system, allowing you to use you IDE as you would normally without the need to transfer files to the machine.

Ansible, like Puppet or Chef is a server management scripting language. However the learning curve is a lot simpler and doesn’t require any software running on the remote servers. It configures the hosts over ssh.

By combining Vagrant with Ansible, it’s very easy to create development environments for developers who are running any common operating system within minutes without having to manually configure their dev environments to suit their operating system.

I have created Vagrant/Ansible setup script which can be found on Github. This will configure a development virtual machine that will have installed the latest versions of Nginx, MariaDB and PHP on Debian 7.

I think it’s worthwhile for any development teams to investigate using virtual machines like this, especially where complex environments are required.

New AFL Websites Built with Yii

1 Comment | This entry was posted on May 14 2013

I was tasked with building the new AFL websites Mark of the Year and Goal of the Year for the 2013 season for the Australian Football League. After gathering the requirements it was excited to find that Yii will be perfect to build these sites.

I love the sink my teeth into a project by starting with database design. The requirements were clear and not too exhaustive so it didn’t take too long to design. From there I was quickly able to build the models, views and controllers with Yii’s great scaffolding tool, Gii.

From this point I could start with the basic page layout and add the business rules to the the models and controllers and tweak the views to meet the functionality. Once the site was fully functional I could then add all the design elements to meet the page layout and styles created by the client.

The tricky part was including the video code into the site with Telstra’s proprietary video embedding code.

It was a great experience and really highlighted how easy and fun it is to build functional websites with Yii.

Websites:

www.markoftheyear.afl.com.au
www.goaloftheyear.afl.com.au

 

Gillette AFL Trade Tracker

0 Comments | This entry was posted on Oct 16 2012

My most recent appointment required me to build a CMS and front-end for the Australian Football League for the trade period. The CMS was built to allow editors to add news items, trades and free agency movements between the 18 clubs.  The front-end was to display the inserted items, but allow the end-user to filter them to given rules. Again, I chose Yii to build this as it’s a great framework for rapid development but also robust and a pleasure to work with.

After designing the database I started building the models, views and controllers before modifying the forms to match the experience required for an easy to use and intuitive CMS. For the main news feed section, the front-end results could be filtered with different filters such as club, date and result type, eg. Trade only or general comment. These filters work together for fine control over the results shown. As each filter is used, the results are returned and populated by AJAX requests with filters being cleared by selecting Live Feed. The challenging part here was deciding on how to have the filters work together in the browser. I ended up building the URL that would be passed in the AJAX request. Session could have worked also but was an issue in load balancing and caching as I’ll point out later.

The second view was a breakdown of trades in and trades out by club. The result for the view were pulled from the same data as in the main feed to save on repetition will adding content. Also with filters that load with AJAX this came together quickly. I’m impressed the way that Yii allows you to reload content for partial views with just a few extra lines of code writing the jQuery for you.

The third view shows the players that fans most want traded. This data is pulled from another website trademachine.afl.com.au which the results are user generated. I could build this view quickly also by implementing a second database that is easy to do in Yii.

The site went live on October 1 and the demand was a lot greater than I was expecting. This resulting in the server becoming overwhelmed and some slow or failed page loads. Being a little unprepared I quickly made new instances of the server and put them all under a load balancer to meet demand. Cloning servers and putting them under a load balancer couldn’t be easier than what is available with Rackspace. This was quick and saved me a lot of pain early on. I then spent some time adding and fine tuning the built-in caching that Yii provides. I had not used caching in Yii before but I was surprised at how easy and effective this is. Although the content should only be cached for 60 seconds on the live feed, the resources being used on the server were dramatically reduced.

This is an example of adding caching to a given part of the site with Yii:

if($this->beginCache('main-content', array(
            'duration'=>60,
            'varyByParam'=>array('filter','club','dateRange'),
            ))) {
                $this->renderPartial('_entryList', array(
                    'dataProvider'=>$dataProvider,
                ));
    $this->endCache(); }

 

This would cache the view to 60 seconds and the varyByParam parameter tells the cache to use GET variables filter, club and dataRange as values to take into account when caching to ensure that each unique request is cached and returned as expected. This is essential as the view has a single URL but the content will change depending on what GET variables are also supplied. If I was to use sessions to keep track of what filters the browser had selected, it would fail through the cache and load balancers so sessions here was not an option.

Overall this was a fun project that required me to provide a solution for an event that I have a lot of interest in. The result is an easy to use CMS with a great user experience in the front-end also.

 

 

Yii Framework Issue With Nginx And SSL

0 Comments | This entry was posted on Oct 09 2011

During the process of moving my websites from one host to another and from Apache to Nginx I came across an issue that had me frustrated yet intrigued. I have a Yii application that I use for my business that I ran over SSL. This was working fine under Apache and for the most part under Nginx. The problem would only come about in Nginx when a form was posted, the browser would be redirected from HTTPS to HTTP mode. Why was this?

After some Google searching, Yii core framework investigation and some trial and error I found that Yii relies on what I determined is a non standard HTTP header ‘HTTPS’ with a value of ‘on’. Nginx does not send this header and on a form post Yii would make the assumption that the browser was in non HTTPS mode.

The core Yii method that determined the protocol is:

public function getIsSecureConnection()
{
    return isset($_SERVER['HTTPS']) && !strcasecmp($_SERVER['HTTPS'],'on');
}

This can be overcome by adding a parameter into the Nginx virtual host record but I see this as a workaround and not a real solution. I thought a simple change from the non standard ‘HTTPS’ header to ‘SERVER_PORT’ (checking that it’s set to 443), which is sent by both Apache and Nginx would be a better solution. I have sent a bug report off to the Yii project with my suggestion so maybe we’ll see it in a future release.

Update: 18 October 2011
My suggested fix was added to the Yii code base but was reverted back out because a site running on port 443 does not necessarily mean it’s running over SSL. There is no standard header that browsers send when running over SSL so therefore a non-ideal solution must be used. I believe the best solution is to add the HTTPS header to the Nginx config as suggested.