Creating a basic RESTful API with Silex

Written by on April 7, 2015

Creating a basic RESTful API with Silex

4b. Install Silex

First create a project folder, for example, it should look like this:

/var/www/silex_demo

Open command prompt and go to the project folder. Execute this line:

composer require silex/silex *

Silex 0011

File structure will look like this:

silex_demo
    --->composer.json
    --->composer.lock
    --->vendor
        --->composer
        --->pimple
        --->psr
        --->silex
        --->symfony
        --->autoload.php

Example

Working example will use jQuery/jQuery Mobile combination (client side), this way we’ll have a nice looking UI.

PHP – index.php

<!DOCTYPE html>
<html>
    <head>
        <title>Silex Demo</title>
        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" /> 
        <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>    
        <script src="js/index.js"></script>		
    </head>
    <body>     
        <div data-role="page" id="index" data-theme="a" >
            <div data-role="header">
                <h3>
                    Silex Demo
                </h3>
            </div>
            
            <div data-role="content">
                <ul data-role="listview" id="user-list">

                </ul>
            </div>
            
            <div data-role="footer" data-position="fixed">
                
            </div>
        </div> 
        <div data-role="page" id="second" data-theme="a" >
            <div data-role="header">
                <h3>
                    Second Page
                </h3>
                <a href="#index" class="ui-btn-left">Back</a>
            </div>
            
            <div data-role="content">
                <ul data-role="listview" id="personal-data" data-theme="a">
 
                </ul>
            </div>
            
            <div data-role="footer" data-position="fixed">
                
            </div>
        </div>  
    </body>
</html>   

Javascript – index.js

$(document).on('pagebeforeshow', '#index', function(){ 
	ajax.ajaxCall("handler.php", true);
});

$(document).on('click', '#user-list li', function(){ 
	ajax.ajaxCall("handler.php/" + $(this).data('listid'), false);
});

var ajax = { 
    parseJSON:function(result){ 
		var obj = jQuery.parseJSON(result);
		$('#user-list').empty();		
		$.each(obj, function(key,row) {
			$('#user-list').append('<li data-listid="' + key + '"><a href="" data-id="' + row.id + '"><img src="http://ia.media-imdb.com/images/M/'+row.image+'"/><h3>' + row.name + '</h3><p>' + row.description + '</p></a></li>');		  
		});
		$('#user-list').listview('refresh');		
    },
    parseJSONDetails:function(result){ 
        var obj = jQuery.parseJSON(result);		
		$('#personal-data').empty();
		$('#personal-data').append('<li><img src="http://ia.media-imdb.com/images/M/'+obj.image+'"></li>');
		$('#personal-data').append('<li>Name: '+obj.name+'</li>');
		$('#personal-data').append('<li>Title: '+obj.description+'</li>');           
		$('#personal-data').listview().listview('refresh'); 
		$.mobile.changePage( "#second");
    },
    ajaxCall: function(url, initialize) {
        $.ajax({
            url: url,
			async: 'true',
			success: function(result) {
				if (initialize) {
					ajax.parseJSON(result);
				} else {
					ajax.parseJSONDetails(result);
				}
			},
     	    error: function(request, error) {
                alert('Network error has occurred, please try again!');
            }
        });
    }
} 

PHP – handler.php

<?php
require_once __DIR__.'/vendor/autoload.php';

$app = new Silex\Application();
// production environment - false; test environment - true
$app['debug'] = true;

$list = array(
 '00001'=> array(
	'name' => 'Peter Jackson',
	'description' => 'Producer | Director',
	'image' => 'MV5BMTY1MzQ3NjA2OV5BMl5BanBnXkFtZTcwNTExOTA5OA@@._V1_SY317_CR8,0,214,317_AL_.jpg',
 ),
 '00002' => array(
	'name' => 'Evangeline Lilly',
	'description' => 'Actress',
	'image' => 'MV5BMjEwOTA1MTcxOF5BMl5BanBnXkFtZTcwMDQyMjU5MQ@@._V1_SY317_CR24,0,214,317_AL_.jpg',
 ),
);

$app->get('/', function() use ($list) {

 return json_encode($list);
});

$app->get('/{id}', function (Silex\Application $app, $id) use ($list) {

 if (!isset($list[$id])) {
	 $app->abort(404, "id {$id} does not exist.");
 }
 return json_encode($list[$id]);
});

$app->run();
?>

Working example

Working Plunker example can be found here:

Demo

Embedded example:


Warning: If you can't see a working example that probably means plnkr.co is down ... again.

Working example uses a little bit different code than the above example. Main difference, JSONP is used instead of JSON. Otherwise, we will receive a cross domain error.

If someone asks, I will also post a cross-domain working example code.

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.



Categories

3 thoughts on “Creating a basic RESTful API with Silex”

  1. Thank you for the article.
    Just wanted to point out if you are blindly copying and pasting (like I was) create a subdirectory called 'js' under the silex_demo dir and drop the index.js there.

Leave a Reply