If you are going to build an android application (it can be any other mobile platform or web too) that manages all the user data on a central database, REST API will be good architectural option to do the communication between the app and the server.
If you consider Evernote, Wunderlist apps, these apps can uninstalled at anytime and once we install them back and login, all our data will be restored. This is because all the data will stored in a cloud database and communication b/w app and database will be done using a REST API.
This tutorial gives enough knowledge about building a REST API for very beginners. As this tutorial seems lengthy, I had divided it into 2 parts. In the 1st part we learn fundamental concepts of REST and do the required setup. In the 2nd part building actual API (writing PHP & MySQL code) is covered.
1. Basics of REST API Design
REST architecture will be useful to build client/server network applications. REST represents Representational State Transfer. Implementing REST is very simple compared to other methods like SOAP, CORBA, WSDL etc., It basically works on HTTP protocol.
Following are the list of things should be considered while building a REST api.
» HTTP Methods
A well-designed RESTful API should support most commonly used HTTP methods (GET, POST, PUT and DELETE). There are other HTTP methods like OPTIONS, HEAD but these are used most often. Each method should be used depending on the type of operation you are performing.
GET | To fetch a resource |
POST | To create a new resource |
PUT | To update existing resource |
DELETE | To delete a resource |
» HTTP Status Code
HTTP status codes in the response body tells client application what action should be taken with the response. For an example if the response code 200, it means on the server side the request is processed successfully and you can expect updated data in the response. As well if the status code is 401, the request is not authorized. An example cause for 401 could be api key is invalid.
It is not necessary to support all HTTP status codes, but supporting at least the following codes should be good enough. Check out list of http codes from restapitutorial.com and Wikipedia
200 | OK |
201 | Created |
304 | Not Modified |
400 | Bad Request |
401 | Unauthorized |
403 | Forbidden |
404 | Not Found |
422 | Unprocessable Entity |
500 | Internal Server Error |
» URL Structure
In REST design the URL endpoints should be well formed and should be easily understandable. Every URL for a resource should be uniquely identified. If your API needs an API key to access, the api key should be kept in HTTP headers instead of including it in URL.
For an example:
GET http://abc.com/v1/tasks/11 – Will give the details of a task whose id is 11
POST http://abc.com/v1/tasks – Will create a new task
» API Versioning
There is a huge discussion on API versioning whether to maintain api version in the URL or in the HTTP request headers. Even though it is recommended that version should be included in the request headers, I feel comfortable to maintain it in the URL itself as it is very convenient on the client side to migrate from one version to another.
Example:
http://abc.com/v1/tasks
http://abc.com/v2/tasks
» Content Type
The Content Type in HTTP headers specifies the kind of the data should be transferred between server and client. Depending upon the data your API supporting you need to set the content type.
For an example, JSON Mime type should be Content-Type: application/json, for XML Content-Type: application/xml. You can find list of supported MIME Types here
» API Key
If you are building a private API where you want to restrict the access or limit to a private access, the best approach is to secure your API using an API key. This article Designing a Secure REST (Web) API without OAuth by Riyad Kalla covers the best way to secure you rest api. But as this article aims at very beginners I am not going with any complex model. So for now we can go with generating a random api key for every user. The user is identified by the api key and all the actions can be performed only on the resources belongs to him.
The API key should be kept in request header Authorization filed instead of passing via url.
Authorization: bf45c093e542f057caee68c47787e7d6
More Knowledge on REST API Design
Following links will explains you the best practices of REST and other principles.
1. RESTful Web services: The basics
2. Stackoverflow discussion
3. A video presentation about REST+JSON API Design – Best Practices for Developers by Les Hazlewood, Stormpath
2. Prerequisite
Before diving deep into this article, it is recommended that you have basic knowledge on PHP, MySQL, JSON parsing and Android PHP, MySQL communication. Go through following links to get basic knowledge.
1. PHP Basics
2. MySQL Prepared Statements
3. Android JSON Parsing
4. How to connect Android with PHP, MySQL
3. Slim PHP Micro Framework
Instead of start developing a fresh REST framework from scratch, it is better go with a already proven framework. Then I came across Slim framework and selected it for the following reasons.
1. It is very light weight, clean and a beginner can easily understand the framework.
2. Supports all HTTP methods GET, POST, PUT and DELETE which are necessary for a REST API.
3. More importantly it provides a middle layer architecture which will be useful to filter the requests. In our case we can use it for verifying the API Key.
Downloading Slim Framework
Download the Slim framework from here (download the stable release) and keep it aside. We are gonna need this some point later after doing required setup.
4. Installing WAMP Server (Apache, PHP and MySQL)
WAMP lets you install Apache, PHP and MySQL with a single installer which reduces burden of installing & configuring them separately. Alternatively you can use XAMP, LAMP (on Linux) and MAMP (on MAC). WAMP also provides you phpmyadmin to easily interact with MySQL database.
Download & install WAMP from http://www.wampserver.com/en/. Choose the correct version which suits your operating system (32bit or 64bit). Once you have installed it, open the program from Start -> All Programs -> Wamp Server -> Start WampServer.
Open http://localhost/ and http://localhost/phpmyadmin/ to verify WAMP is installed successfully or not.
5. Installing Chrome Advanced REST client extension for Testing
Chrome Advanced REST client extension provides an easy way to test the REST API. It provides lot of options like adding request headers, adding request parameters, changing HTTP method while hitting an url. Install Advanced REST client extension in chrome browser. Once you installed it you can find it in chrome Apps or an icon at the top right corner.
Alternatively if you prefer using firefox, you can go for Poster add-on to test the API.
6. REST API for Task Manager App
To demonstrate REST API I am considering an example of Task Manager App with very minimal functionalities.
1. User related operations like registration and login
2. Task related operations like creating, reading, updating and deleting task. All task related API calls should include API key in Authorization header field.
Following are the list of API calls we are going to build in this tutorial. You can notice that same url endpoint is used for multiple api calls, but the difference is the type of HTTP method we use to hit the url. Suppose if we hit /tasks with POST method, a newer task will be created. As well if we hit /tasks with GET method, all the tasks will be listed.
URL | Method | Parameters | Description |
/register | POST | name, email, password | User registration |
/login | POST | email, password | User login |
/tasks | POST | task | To create new task |
/tasks | GET | Fetching all tasks | |
/tasks/:id | GET | Fetching single task | |
/tasks/:id | PUT | Updating single task | |
/tasks/:id | DELETE | task, status | Deleting single task |
7. Creating MySQL Database
For this app we don’t need a complex database design. All we need at this stage is only three tables. You can always add few more tables if you want to extend the functionality. I have created three tables users, tasks and user_tasks.
users – All user related data will be stored here. A row will inserted when a new user register in our app.
tasks – All user tasks data will be stored in this table
user_tasks – Table used to store the relation between user and his tasks. Basically we store users id and task id in this table.
Open the phpmyadmin from http://localhost/phpmyadmin and execute the following SQL queries. As well if you are familiar with phpmyadmin, you can use phpmyadmin graphical interface to create tables.
CREATE DATABASE task_manager; USE task_manager; CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(250) DEFAULT NULL, `email` varchar(255) NOT NULL, `password_hash` text NOT NULL, `api_key` varchar(32) NOT NULL, `status` int(1) NOT NULL DEFAULT '1', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ); CREATE TABLE IF NOT EXISTS `tasks` ( `id` int(11) NOT NULL AUTO_INCREMENT, `task` text NOT NULL, `status` int(1) NOT NULL DEFAULT '0', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ); CREATE TABLE IF NOT EXISTS `user_tasks` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `task_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`), KEY `task_id` (`task_id`) ); ALTER TABLE `user_tasks` ADD FOREIGN KEY ( `user_id` ) REFERENCES `task_manager`.`users` ( `id` ) ON DELETE CASCADE ON UPDATE CASCADE ; ALTER TABLE `user_tasks` ADD FOREIGN KEY ( `task_id` ) REFERENCES `task_manager`.`tasks` ( `id` ) ON DELETE CASCADE ON UPDATE CASCADE ;
After executing these queries go through each tables and make sure that everything created correctly.
Until now we are done with getting your system ready for development. The next article How to create REST API for Android app using PHP, Slim and MySQL – Day 2/2 covers the overall process of starting and finishing the PHP and MySQL project.
Hi there! I am Founder at androidhive and programming enthusiast. My skills includes Android, iOS, PHP, Ruby on Rails and lot more. If you have any idea that you would want me to develop? Let’s talk: ravi@androidhive.info
I am so looking forward to the next article. This is looking very interesting
Yeah, It will be posted on next day 🙂
Check out the next part
http://www.androidhive.info/2014/01/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-23/
Hii ravi i am geting
{
error: true
message: “Required field(s) name, email, password is missing or empty”
}
please tell me how to solve this problem i am stcing from 2 days …
jjknnnjnjnjn
Hello Ravi , How to do the setup for this REST api example in Cpanel with unix server.
It’s useful, thanks.
Very useful and nice presentation.
Thanks for your great articles and projects all over androidhive.info
Awesome article! I’m relay looking forward for next one!
Good article. Looking forward to the next one.
Nice Article,very interesting…..and waiting for the next one…… 🙂
Nice one
Easy to understand as usual… Thanks.. Waiting for next one.
Nice post @Ravi Tamada:disqus… Got to know about Slim framework through this post.. 🙂
I am glad it helped you 🙂
Ravi, just curious, are you using Eclipse or Android Studio for this?
I am using Eclipse.
Ravi sir not getting how to put value in header, pls help me
Are you trying in chrome browser? If yes check the video in second part. You have to set ‘Authorization’ field in the header and the value should be api key.
Can you show some example code how to pass?
like etc
etc
i am trying to open second part link but ……………. still not found
http://www.androidhive.info/2014/01/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-23/
Very nice article for beginners of REST. Thank you so much Ravi.
Thank you so much. It’s very good article.
Very nice tutorial ravi, i have a question regarding a security issue:
1) How can i handle an expiration date for the api-key? because if i store the api-key in SharedPreferences and send the api_key everytime with the request, the user will be forever logged in
Hii ravi i am geting
{
error: true
message: “Required field(s) name, email, password is missing or empty”
}
please tell me how to solve this problem i am stcing from 2 days …where is fault i am not getting and its telling 404 bad request…
Because you need to fill not headers, but Payload values. First choice POST method for register not GET
The third part would be sweet!
HI RAVI,
I HAVE NOT FIND ANY GOOD EXAMPLE TO PARSE REST API USING JSON PARSING CAN HELP ME.
use retrofit 2.1.
Do you have it to work with retrofit 2 ? if yes can you share the source code? 🙂
Very good explanation with diagrams and videos. Thanks a lot.
How can we implement this tutorial on hosting?
Thankyou so much ravi……. It’s nice article to learn REST API for the beginners….
The tutorial was excellent.It works fine for me in localhost but not on live server.On uploading the project to live server i got 404 not found exception..Anyone came across this issue..Pls help….
Hello there,
I want to download the sources of the tutorial but when I sign up, I never get the email that would validate my account.
How can I do?
Thank you in advance
Excellent tutorial, Thank you very much!!
You are welcome.
I am confused! Why I need the slim framework and if it must, how can i create one for myself. Please also guide me through the android app code (I already know the “Connecting sql to android” part.
please reply to my question
Hi,
First thank you for the tutorial it’s really great.
I try to test the REST API but I’ve got some problems.
I work on LAMP (Debian), I download the source from you website (thanks) but when I try to test with Advanced Rest Client I’ve got the 404 error
If you have some ideas about where is the problem I’ll be very grateful
Thank you, Have a nice day
up
I download sources and I follow video instructions for test the API but I always got a 404 Error.
I try to copy another file “index.html” in /task_manager/v1/ and it works.
I try to modify .htaccess as ‘Tom L.’ has advised (in the 2/2 page of tutorial) but I’ve got the same bad result
Is there some modifications that we have to do to use source on Linux installation ?
(Informations: Debian=7.6, Php=5.4.4, Apache=2.2.22, MySQL=5.5.38)
Thank you
Hi. Did you solve this 404 error problem?
thanks,
Paulo Gomes
i’m havng the sameproblemright now/
do we need to restar tour compters?
Hi, I still have tried it yet but can you please explain how to do a multipart-data method? a simple example for the register method with a profile image would be great!
Thank you for all these tutorials,especially for image caching!
Ravi, what are advantages/disadvantages of Slim framework over other more popular solutions like Restlet and Spring? Why did you chose Slim? Thank you
Your download code button isn’t working 🙁
I appreciate the tutorial. Using the mysql native driver really caused me fits though. I couldn’t (and still can’t) get it working under MAMP or AMPPS, so I re-wrote all the database handler stuff using PDO.
Hello,
Thank you for the tutorial Ravi.
Is there somebody succeed to run the code on LAMP ?
If you have advice to do it, I would be grateful… sorry if it’s stupid but I’m a noob :s
Bye
Hi Ravi,
Thanks for the tutorial, helped me a great deal.
For those struggling with get_result error in php.
index.php:
/**
* Listing all tasks of particual user
* method GET
* url /tasks
*/
$app->get(‘/tasks’, ‘authenticate’, function() {
global $user_id;
$response = array();
$db = new DbHandler();
// fetching all user tasks
$result = $db->getAllUserTasks($user_id)
;
if (!$result)
throw new Exception(“Database Error [{$this->database->errno}] {$this->database->error}”);
if ($result != NULL) {
$response[“error”] = false;
$response[“tasks”] = array();
// looping through result and preparing tasks array
foreach ($result as $task)
{
$tmp = array();
$tmp[“id”] = $task[“id”];
$tmp[“task”] = $task[“task”];
$tmp[“status”] = $task[“status”];
$tmp[“createdAt”] = $task[“created_at”];
array_push($response[“tasks”], $tmp);
}
echoRespnse(200, $response);
}
else
{
$response[“error”] = true;
$response[“message”] = “The requested resource doesn’t exists”;
echoRespnse(404, $response);
}
});
DB_Handler.php:
public function getAllUserTasks($user_id) {
$stmt = $this->conn->prepare(“SELECT t.id, t.task, t.status, t.created_at from tasks t, user_tasks ut WHERE t.id = ut.task_id AND ut.user_id = ?”);
$stmt->bind_param(“i”, $user_id);
$tasks = array();
if ($stmt->execute())
{
$stmt->bind_result($id, $task, $status, $created_at);
while($stmt->fetch())
{
$tmp = array();
$tmp[“id”] = $id;
$tmp[“task”] = $task;
$tmp[“status”] = $status;
$tmp[“created_at”] = $created_at;
array_push($tasks, $tmp);
}
}
$stmt->close();
return $tasks;
}
thanks a lot sir..you saved my day !!! 🙂 🙂
Really appreciable !!!
Thanks a lot man !!! It really helped me a lot…Thanks again… 🙂
Thanks man!!! 🙂 It helped me a lot
Hi Ravi,
Thanks a lot for your work. It is helping me and a lot of people.
Actually, I am developing an app to upload a file from android phone to a remote server which needs authentication. UploadToServer.php file is present in that server which helps in receiving the file from the phone and stores in the server in required path. But to run this php file from the URL in the app, authentication must be given to the app.
I would like to know how to provide this authentication (login details) to the URL (to run php file in server) present in my android app. Normally in various blogs, I can only see examples without authentication.
Thanks you very much,
Raj Bharath
Hi ravi,wonderful work,could you tell me how to deploy rest api in the market ,means where from to buy domain,,any help would be great..
I want to use a REST api (for example the above api) in my php script for my website.How do I call them for registering users like in forms using $_POST ?
public static class Webservice_ValidUser {
//private static final String URL = “http://api.ogoing.com/user.asmx?op=ValidUser”;
private static final String URL = urlmain+”user.asmx?op=ValidUser_New”;
private static final String SOAP_ACTION_NEW = “http://www.ogoingapi.com/ValidUser_New”;
/**
* Getting Contact information
*
* @param attendeeCredentials
* @param inSeqNum
* @return GetAttendeesContactInfoResponse
*/
public static JSONObject callWebServiceJson(String UserName, String Password, String DeviceId) {
JSONObject jsonObj = null;
String ValidLogin = “”
+ “”
+ “” + “”
+ “” + UserName + “” + “”
+ Password + “” + “” + portal
+ “” + “” + DeviceId + “”
+”android”
+ “” + “” + “”;
DefaultHttpClient httpClient = new DefaultHttpClient();
String envoloper = String.format(ValidLogin);
// request parameters
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 15000);
// set parameter
HttpProtocolParams.setUseExpectContinue(httpClient.getParams(),true);
// POST the envelope
HttpPost httppost = new HttpPost(URL);
// add headers
// Set Method Action
httppost.setHeader(“soapaction”, SOAP_ACTION_NEW);
httppost.setHeader(“Content-Type”, “text/xml; charset=utf-8”);
String response = “”;
try {
// the entity holds the request
HttpEntity entity = new StringEntity(envoloper);
httppost.setEntity(entity);
// Response Handler
ResponseHandler responseHandler = new ResponseHandler() {
@Override
public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
// get response entity
HttpEntity entity = response.getEntity();
// read the response as byte array
StringBuffer out = new StringBuffer();
byte[] b = EntityUtils.toByteArray(entity);
// write the response byte array to a string buffer
out.append(new String(b, 0, b.length));
return out.toString();
}
};
// Getting the response
response = httpClient.execute(httppost, responseHandler);
// Sending the Response to parsing class
String stt[] = response.split(“”);
String stt2[] = stt[1].split(“”);
Log.i(“”, “stt” + stt);
Log.i(“”, “stt2” + stt2);
String my_string = stt2[0];
Spanned abc = Html.fromHtml(Html.fromHtml(my_string).toString());
String my_final_string = abc.toString();
jsonObj = new JSONObject(my_final_string);
String uname = jsonObj.getString(“UserName”);
Log.i(“uname” + uname, “my_string” + my_string);
} catch (Exception exc) {
exc.printStackTrace();
}
return jsonObj;
}
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(“http://vmss.co.in/smarttransport/getdetail.php”);
MultipartEntity data_to_send = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
data_to_send.addPart(“journeyId”, new StringBody(journeyId));
data_to_send.addPart(“delete”, new StringBody(“1”));
httppost.setEntity(data_to_send);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
result=is.toString();
if(result != null)
{
flag = true;
}
}catch(Exception e)
{
Log.e(“log_tag”, “Error in http connection”+e.toString());
}
if(flag == true)
{
try
{
System.out.println(“1″);
BufferedReader reader = new BufferedReader(new InputStreamReader(is,”iso-8859-1”),8);
System.out.println(“2”);
sb = new StringBuilder();
System.out.println(“3”);
sb.append(reader.readLine() + “n”);
String line=”0″;
while ((line = reader.readLine()) != null)
{
sb.append(line);
}
is.close();
result=sb.toString();
System.out.println(“else “+result);
}catch(Exception e)
{
}
}
return null;
}
Simply superb tutorial..keep it up man!!! you helped me manier times before…thank you so much 🙂
You are welcome 🙂
Many thanks.
Hi, Ravi or Anyone.
Does anyone knows where i can find a good tutorial on how to consume (use) this restfull api from my android application?
thanks a lot @Ravi Tamada:disqus
Hai sir,
Could you plse tell me where i get example api’s for doing jsonparsing.
I think you are looking for http://www.programmableweb.com/ ;
http://graph.facebook.com/youtube
Check out the above link to see the facebook’s graph api which shows youtube’s fan page details.
Ravi, I’ve a doubt. Why 3 tables?.
Can i add a new column to `tasks` named `user_id` which refers to the user’s id who made the task (FK). ?? Is that a bad approach ??
good Approach of course. Plus, maybe, user’s who like and dislike a task, and comments from other users. thanks for the tip.
great article, very helpful! thank you
Anyone got this working in LAMP?BTW very helpful tutorial
I am using it on Ubuntu 14.04
Hi, great tutorial, thanks!
Where is the one for the android implementation?
how show the users from database in Advanced Rest Client
please help need index.php for registration and login
How can I get solve my problem of api key is missing
Please help. I get this error while listing user’s tasks :-
PHP Fatal error: Call to undefined method mysqli_stmt::get_result()
Install mysqlnd drivers.