Pemrograman RESTful API - komputasi.files.wordpress.com · •Resources dikenali dengan global ID...
Transcript of Pemrograman RESTful API - komputasi.files.wordpress.com · •Resources dikenali dengan global ID...
Pemrograman RESTful [email protected]
Apa itu?
Apa itu REST?
REST bermakna:
• REpresentational
• State
• Transfer
REpresentational ? State ? Transfer ?
• Merepresentasikan status dari database pada suatu waktu. Caranya?
• REST merupakan suatu architectural style yang didasarkan pada web-standard dan protokol HTTP.
• Dalam arsitektur berbasis REST semua dianggap Resource.
• Resource diakses via suatu interface umum berbasiskan pada metode standard HTTP.
• Biasanya kita mempunyai REST server yang menyediakan akses ke resources dan REST client yang mengakses dan memodifikasi REST resources tersebut.
REpresentational ? State ? Transfer ?
• Setiap resource harus mendukung operasi umum HTTP.
• Resources dikenali dengan global ID (biasanya berupa URI atau URL).
• REST memungkinkan resources tersebut mempunyai representasi berbeda, seperti text, XML dan JSON.
• Sifatnya Stateless. Sangat cocok untuk sistem terdistribusi.
• Komponen Stateless dapat secara bebas di-redeploy jika terjadi kegagalan, dan dapat di-scale untuk mengakomodir perubahan beban.
• Ini karena suatu request dapat diarahkan ke instance tertentu dari komponen.
Metode HTTP
• Metode PUT, GET, POST dan DELETE biasa digunakan dalam arsitektur berbasis REST
Metode HTTP
Operasi CRUD
Keterangan
POST INSERT Menambahkan ke sumber daya yang ada
PUT UPDATE Memperbarui sumber daya yang ada
GET SELECT Mengambil suatu sumber daya. Sumber daya itu tidak pernah berubah via request GET
DELETE DELETE Menghapus suatu sumber daya
Arsitektur
Contoh HTTP Request
Suatu baris kosong memisahkan header & body
Body (badan) request message
Header dari request message
Baris request
Header request
Contoh HTTP Response
Suatu baris kosong memisahkan header & body
Body (badan) response message
Header dari response message
Baris status
Header respon
HTTP REST Request:
GET https://www.myhost.com/api/v1/user/1/cities
Baca, Semua kota untuk user dengan id bernilai 1
GET /user/1/cities http/1.1host: https://www.myhost.com/api/v1Content-Type: application/jsonAccept-Language: us-enstate_id: 2
HTTP REST API Request
HTTP REST Response:
HTTP/1.1 200 OK (285ms)Date: Fri, 21 Apr 2017 10:27:20 GMTServer: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips PHP/7.0.16X-Powered-By: PHP/7.0.16Content-Length: 109Keep-Alive: timeout=5, max=100Connection: Keep-AliveContent-Type: application/json; charset=UTF-8
{"status":"success","message":"CityList","data":[{"city_name":"Visakhapatnam"},{"city_name":"Vijayawada"}]}
HTTP REST API Response
Kode Status Respon HTTP
• 1xx Kode mengenai informasi
• 2xx Kode jika sukses
• 3xx Kode redirection
• 4xx Kode error Client
• 5xx Kode error Server
• Lihat di https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
Poin-poin PentingBagi REST API
Gunakan Kata Benda, Bukan Kata Kerja di URL
Maksud Metode Salah Benar
Memperoleh daftar user GET /getAllCars /users
Membuat pengguna baru POST /createUser /users
Menghapus user DELETE /deleteUser /users/10
Mendapatkan saldo user GET /getUserBalance /users/11/balance
Gunakan Kata Benda Jamak
• Jangan dicampur kata benda tunggal dan jamak. Pastikan tetap simpel dan hanya gunakan bentuk jamak untuk semua sumber daya.• /cars bukan /car
• /users bukan /user
• /products bukan /product
• /settings bukan /setting
Metode GET Harus Tidak Mengubah Status
• Gunakan metode PUT, POST dan DELETE bukan GET untuk mengubah status.
• Jangan gunakan metode GET atau parameter Query untuk mengubah satus:• GET /users/711?aktifkan atau
• GET /users/711/aktifkan
Gunakan Sub-resources untuk Relasi:
• Jika suatu sumber daya berhubungan dengan sumber daya lain, gunakan sub-sumber daya• GET /cars/711/drivers/ (mengembalikan daftar drivers untuk car 711)
• GET /cars/711/drivers/4 (mengembalikan driver #4 untuk car 711)
• Disebut juga Resources Chaining
• Resources dalam URL RESTful dapat disambung untuk membentuk suatu hirarki relasi.• resource1/{id}/resource2/{id}
• Selalu gunakan koleksi diikuti satu anggotanya• …/customers/123/orders/456/items/789
Items dimiliki orders, orders dimiliki oleh customers.
Resources Chaining
• URL harus dapat telusur (Hackable) ‘sampai pohonnya’• User harus mampu menghapus leaf path-nya dan memperoleh respon balik
yang diharapkan.
…/customers/123/orders
Menghapus ujung URL sampai dengan orders harus mengembalikan semua orders untuk customer tersebut.
• Jangan gunakan anggota yang dimiliki koleksi tanpa mendapatkan koleksi tersebut dalam path terlebih dahulu.• Bagus: /customers/123/orders/456/items/789
• Jelek: /customers/123/orders/456/789
Gunakan Header HTTP untuk Format Serialisasi
• Client dan server perlu mengetahui format yang digunakan selama komunikasi.
• Format tersebut harus dispesifikasikan dalam HTTP-Header.• Content-Type mendefinisikan format request.
• Accept mendefinisikan daftar format dari respon yang acceptable.
Versioning Itu Penting
• Membuat versi API adalah wajib
• Jangan rilis API tanpa versi (hanya boleh saat latihan).
• Gunakan bilangan bulat sederhana dan hindari notasi titik seperti 2.5
• URL digunakan untuk merepresentasikan API versioning, dimulai dengan huruf “v”• /blog/api/v1
Tangani Error dengan Kode Status HTTP
Kode Keterangan Kode Keterangan
200 OK (Everything is working) 403 Forbidden (The server understood therequest, but is refusing it or the access isnot allowed)
201 OK (New resource has been created) 404 Not found (There is no resource behind theURI)
204 OK (Resource successfully deleted) 405 Method not allowed
400 Bad Request (The request was invalid or cannot be served. The exact error should be explained in the error payload. E.g. “The JSON is not valid“)
408 Request timeout
401 Unauthorized (The request requires anuser authentication)
500 Internal server error
Filtering:
• Gunakan suatu parameter query unik untuk semua field atau bahasa query untuk penyaringan• GET /cars?color=red (Mengembalikan daftar mobil merah)
• GET /users?name=tom (Mengembalikan daftar pengguna yang namanya cocok dengan tom)
Pengurutan
• Mungkinkan pengurutan ascending dan descending terhadap banyak field
GET /cars?sort=-manufacturer,+model
Untuk mengembalikan sedaftar cars terurut secara descendingberdasarkan manufacturers dan ascending berdasarkan models)
Paging:
• Gunakan limit dan offset.
• Fleksibel bagi pengguna dan umum dalam penanganan hasil query database.
• Sebaiknya, ditetapkan default limit=20 dan offset=0• GET /cars?offset=10&limit=5
Alias untuk Query Umum
• Agar pemanfaatan API lebih nyaman bagi rerata consumer,pertimbangkan untuk memaket himpunan kondisi ke dalam pathRESTful yang mudah diakses.
• Sebagai contoh, kasus di bawah ini dapat ditiru:• POST /users (User Register: Membuat user baru)
• POST /users/login (User Login: membuatkan auth token untuk otentikasi user)
Pengembangan REST API Secara Mudah?
• Checkout Slim - Suatu microframework untuk PHP.• Dokumentasi: https://www.slimframework.com/docs/
Contoh Slim: Hello World
<?php
require 'vendor/autoload.php';
$app = new \Slim\App();
$app->get('/ping', function ($request, $response) {
$body = json_encode(['ack' => time()]);
$response->write($body);
$response = $response->withHeader(
'Content-Type', 'application/json');
return $response;
});
$app->run();
PSR-7?
Tentang HTTP
• Request:{METHOD} {URI} HTTP/1.1
Header: value1,value2
Another-Header: value
Message body
• Response:HTTP/1.1 {STATUS_CODE} {REASON_PHRASE}
Header: value
Message body
PHP Saat Ini
• Request:• $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
• apache_request_headers()
• php://input
• Response:• header()
• echo (& ob_*() family)
PSR 7: HTTP Messaging
• Hanya beberapa interface:• RequestInterface (& ServerRequestInterface)
• ResponseInterface
• UriInterface
• UploadedFileInterface
Fitur Kunci 1: Immutability
Request, Response, Uri & UploadFile bersifat immutable
$uri = new Uri('https://api.joind.in/v2.1/events');
$uri2 = $uri->withQuery('?filter=upcoming’);
$request = (new Request())
->withMethod('GET')
->withUri($uri2)
->withHeader('Accept', 'application/json')
->withHeader('Authorization', 'Bearer 0873418d');
Fitur Kunci 2: Streams
Message bodies adalah streams
$body = new Stream();
$body->write('<p>Hello');
$body->write('World</p>’);
$response = (new Response())
->withStatus(200, 'OK')
->withHeader('Content-Type', 'application/header')
->withBody($body);
Negosiasi Metode HTTP
Negosiasi Metode HTTP
$ http --json PUT http://localhost:8888/ping
HTTP/1.1 405 Method Not Allowed
Allow: GET
Connection: close
Content-Length: 53
Content-type: application/json
Host: localhost:8888
X-Powered-By: PHP/5.6.14
{
"message": "Method not allowed. Must be one of: GET"
}
Routing Metode HTTP
$app->get('/author', function($req, $res) {});
$app->post('/author', function($req, $res) {});
$app->get('/author/{id}', function($req, $res) {});
$app->put('/author/{id}', function($req, $res) {});
$app->patch('/author/{id}', function($req, $res) {});
$app->delete('/author/{id}', function($req, $res) {});
$app->any('/author', function($req, $res) {});
$app->map(['GET', 'POST'], '/author', /* … */);
Rute Dinamis
$app->get('/author/{id}’, function($request, $response, $args) {
$id = $args['id'];
$author = $this->authors->loadById($id);
$body = json_encode(['author' => $author]);
$response->getBody()->write($body);
$response = $response->withHeader(
'Content-Type', 'application/json');
return $response;
});
Regex
// hanya bilangan
$app->get('/author/{id:\d+}', $callable);
// segmen opsional
$app->get('/author[/{id:\d+}]', $callable);
$app->get('/news[/{y:\d{4}}[/{m:\d{2}}]]', $callable);
Penanganan Content-type
Penanganan Content-type
Header Content-type menentukan format dari data masuk (incoming)
$ curl -X "POST" "http://localhost:8888/author" \
-H "Content-Type: application/json" \
-d '{ "name":"Terry Pratchett" }'
Read dengan getBody()
$app->post('/author',
function ($request, $response, $args) {
$data = (string)$request->getBody();
return $response->write(print_r($data, true));
}
);
Output:
{ "name":"Terry Pratchett" }
Read dengan getParsedBody()
$app->post('/author’, function ($request, $response, $args) {
$data = (array)$request->getParsedBody();
return $response->write(print_r($data, true));
});
Output:
Array
(
[name] => Terry Pratchett
)
Bekerja juga dengan XML
curl -X "POST" "http://localhost:8888/author" \
-H "Content-Type: application/xml" \
-d "<author><name>Terry Pratchett</name></author>“
Output:
Array
(
[name] => Terry Pratchett
)
Dan Data Form
curl -X "POST" "http://localhost:8888/author" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "name=Terry Pratchett"
Output:
Array
(
[name] => Terry Pratchett
)
Format Lagi? Misal CSV
name,dob
Terry Pratchett,1948-04-28
Andy Weir,1972-06-17
dengan curl:
curl -X "POST" "http://localhost:8888/author" \
-H "Content-Type: text/csv" \
-d $'name,dob
Terry Pratchett,1948-04-28
Andy Weir,1972-06-17'
Mendaftarkan Tipe Media
$request->registerMediaTypeParser('text/csv',function ($input) {$data = str_getcsv($input, "\n");$keys = str_getcsv(array_shift($data));
foreach ($data as &$row) {$row = str_getcsv($row);$row = array_combine($keys, $row);
}
return $data;
}
);
Hasil
Array
(
[0] => Array
(
[name] => Terry Pratchett
[dob] => 1948-04-28
)
[1] => Array
(
[name] => Andy Weir
[dob] => 1972-06-17
)
)
Middleware
Middleware is code that exists between the request and response, and which can take the incoming request, perform actions based on it, and
either complete the response or pass delegation on to the next middleware in the queue.
Matthew Weier O'Phinney
Middleware
• Manipulasi dari
Respon ke Browser
Middleware
function ($request, $response, callable $next = null) {
// do something before
// call through to next middleware
if ($next) {
$response = $next($request, $response);
}
// do something with $response after
return $response;
}
Tipe Media Middleware
$app->add(function ($request, $response, $next) {
$request->registerMediaTypeParser('text/csv',function ($input) {
$data = explode("\n", $input);
$keys = str_getcsv(array_shift($data));
foreach ($data as &$row) {
$row = str_getcsv($row);
$row = array_combine($keys, $row);
}
return $data;
});
return $next($request, $response);
});
Menghargai Accept header
Menghormati Accept Header
Mengembalikan data dalam format yang diharapkan oleh client
curl -X "POST" "http://localhost:8888/author" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{ "name":"Terry Pratchett" }'
Mengembalikan JSON
$app->post('/author’, function ($request, $response, $args) {
$author = new Author($request->getParsedBody());
$this->authors->save($author);
$response = $response->withJson($author->asArray());
$response = $response->withStatus(201);
return $response;
});
Mengembalikan JSON
HTTP/1.1 201 Created
Content-type: application/json
Content-Length: 106
{
"id":"2ff815ad-491d-4db8-a025-363516e7c27e",
"name":"Terry Pratchett",
"biography":null
}
Mengembalikan XML
curl -X "POST" "http://localhost:8888/author" \
-H "Accept: application/xml" \
-H "Content-Type: application/json" \
-d '{ "name":"Terry Pratchett" }'
Menentukan Tipe Media
$ composer require willdurand/negotiation
// find preferred format from Accept header
function determineMediaType($acceptHeader) {$negotiator = new \Negotiation\Negotiator();$known = ['application/json', 'application/xml'];$mediaType = $negotiator->getBest($acceptHeader, $known);
if ($mediaType) {return $mediaType->getValue();
}
return 'application/json';
}
Menformat Output
$acceptHeader = $request->getHeaderLine('Accept')
$mediaType = determineMediaType($acceptHeader);
switch ($mediaType) {
case 'application/xml':
$response->getBody()->write(arrayToXml($data));
break;
case 'application/json':
$response->getBody()->write(json_encode($data));
break;
}
return $response->withHeader("Content-Type", $mediaType);
Output XML
HTTP/1.1 201 Created
Content-type: application/xml
Content-Length: 131
<?xml version="1.0"?>
<root>
<id>98c22fa3-bf97-48c8-accd-025470c34b46</id>
<name>Terry Pratchett</name>
<biography/>
</root>
Ada Komponen Untuk Ini
$ composer require akrabat/rka-content-type-renderer
Penggunaannya:
$renderer = new RKA\ContentTypeRenderer\Renderer();
$response = $renderer->render($request, $response, $data);
return $response->withStatus(201);
Penanganan Error
Penanganan Error
• Method not allowed
• Not found
• Generic error
Method not allowed
curl -X "PUT" "http://localhost:8888/ping"
HTTP/1.1 405 Method Not Allowed
Content-type: text/html;charset=UTF-8
Allow: GET
<html>
<body>
<h1>Method not allowed</h1>
<p>Method not allowed. Must be one of:
<strong>GET</strong></p>
</body>
</html>
Not found
curl -X "GET" "http://localhost:8888/foo" \
-H "Accept: application/xml"
HTTP/1.1 404 Not Found
Content-Type: application/xml
Allow: GET
<root><message>Not found</message></root>
Error Tambahan (Personal)
$app->get('/author/{id}’,
function ($request, $response, $args) {
$author = $this->authors->loadById($args['id’]);
if (!$author) {
return $this->notFoundHandler($request, $response);
}
// continue with $author
}
);
Generic error
$app->get('/error',
function ($request, $response, $args) {
throw new \Exception("Something has gone wrong!");
});
curl -X "GET" "http://localhost:8888/error" -H "Accept: application/json"
HTTP/1.1 500 Internal Server Error
Content-type: application/json
Content-Length: 43
{
"message": "Slim Application Error"
}
Informasi Eksepsi (Exception)
$settings = [
'settings' => [
'displayErrorDetails' => true,
]
];
$app = new Slim\App($settings);
Informasi Eksepsi
HTTP/1.1 500 Internal Server ErrorContent-type: application/json {
"message": "Slim Application Error","exception": [
{"type": "Exception","code": 0,"message": "Something has gone wrong!","file": "/dev/an-api/app/routes.php","line": 8,"trace": [
"#0 [internal function]: Closure->{closure} …"#2 /dev/an-api/vendor/slim/slim/Slim/Route.php(……
Menangani Warnings
$app->get('/error',
function ($request, $response, $args) {
ini_get(); // will generate a warning
});
// convert errors into exceptions
set_error_handler(function ($level, $msg, $file, $ln) {
if (!(error_reporting() & $level)) { return; }
throw new \Exception($msg, $level);
});
Versi
Versi
Dua pilihan:
• Segment di dalam URL:
http://api.example.com/v1/author
• Tipe Media:
Accept: application/vnd.rka.author.v1+json
URL Segment
Use route groups:
$app->group('/v1', function () {
// http://api.example.com/v1/author
$this->get('/author',
function ($request, $response) { /*…*/ }
);
// http://api.example.com/v1/author/123
$this->get('/author/{id}',
function ($request, $response, $args) { /*…*/ }
);
});
Media Type Versioning
• Pertama, mari kita lihat dukungan dependency injection dari Slim
Container
Daftarkan layanan dengan DIC
$settings = ['settings' => ['dsn' => 'sqlite:data/bookshelf.db',]];
$app = new Slim\App($settings);
$container = app->getContainer();
$container['pdo'] = function ($c) {
return new PDO($c['settings']['dsn']);
};
$container['authors'] = function ($c) {
return new Bibliotheque\AuthorMapper($c['pdo']);
};
Kelas Controller
Daftarkan controller dengan container
$container['AuthorController'] = function ($c) {
$renderer = $c->get('renderer');
$authors = $c->get('authors');
return new App\AuthorController($renderer, $authors);
}
// Register with router:
$app->get('/author', 'AuthorController:listAll');
Controller Author
class AuthorController {
public function __construct($renderer, $authors) {
$this->renderer = $renderer;
$this->authors = $authors;
}
public function listAll($req, $res) {
$authors = $this->authors->fetchAll();
$data = ['authors' => $authors];
return $this->renderer->render($req, $res, $data);
}
}
Media Type Versioning
Pilih controller berdasarkan pada Accept header:
$container['AuthorController'] = function ($c) {
$request = $c->get('request');
$acceptHeader = $request->getHeaderLine('Accept');
if (strpos($acceptHeader,
'application/vnd.rka.author.v2') !== false) {
return new App\V2\AuthorController(/*…*/);
}
return new App\V1\AuthorController(/*…*/);
};
Filtering & Validasi
Filtering & Validasi
Route middleware memastikan callable clean!
$app->post(
'/author',
'AuthorController:addNewAuthor'
)->add('AuthorValidator');
AuthorValidator
class AuthorValidator {
public function __invoke($req, $res, $next) {
$data = $req->getParsedBody();
$validator = new \Valitron\Validator($data);
$validator->rule('required', 'name');
if (!$validator->validate()) {
$e = ['errors' => $validator->errors()];
$response = $this->renderer->render($req, $res, $e);
return $response->withStatus(422);
}
return $next($req, $res);
}
}
Validasi
curl -X "POST" "http://localhost:8888/author" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":""}'
HTTP/1.1 422 Unprocessable Entity
Content-type: application/json
Content-Length: 84
{
"errors": {
"name": [
"Name is required"
]
}
}
Rangkuman
API yang bagus berurusan dengan:• Negosiasi metode HTTP
• Penanganan Content-type
• Menghormati Accept header
• Error handling
• Versions
• Filtering & Validasi
Sumder Daya
• http://phptherightway.com
• http://slimframework.com/docs
• https://github.com/slimphp/Slim
• http://akrabat.com/category/slim-framework/
• http://ryanszrama.com/topics/slim
Praktek
• RESTful API dengan PHP
• RESTful API dengan Slim Framework
Perangkat & Tutorial
http://10.5.10.160/sister/
Membangun RESTful Web Service dengan PHP (Native)
Langkah-Langkah: Persiapan
• Pastikan PHP dan Database Server (MySQL misalny) jika diperlukan. Jika perlu Web Server (misal Apache), silakan diinstall. Lebih mudah menggunakan paket seperti XAMPP
• Buat folder proyek. Di sini semua file web service RESTful diletakkan, misal: “c:\xampp\htdocs\produk”
• Tetapkan semua rute (URL) untuk web service, mulai untuk metode GET, POST, PUT dan DELETE
GET /api/products Meretrieve semua produkGET /api/products/:id Meretrieve satu produk yang kunci :id POST /api/products Menambahkan suatu produk baru PUT /api/products/:id Mengupdate satu produk yang kunci :idDELETE /api/products/:id Menghapus satu produk yang kunci :id
Langkah-langkah: Persiapan
• Jalankan Apache Web Server dan MySQL Database Server (via Control Panel XAMPP)
• Membuat database bernama “rest_api”, dapat menggunakan PHPMyAdmin (localhost/phpmyadmin)
• Buat tabel bernama “products”, dengan field: • id : integer, auto_inc
• product_name : varchar (100)
• price : float
• quantity : integer
• Seller : varchar (30)
Database rest_api tabel products
Masukkan data contoh, 1 s.d 5 record.
Langkah-Langkah: Membuat Web Service
• Membangun koneksi ke Database Server
//koneksi ke database
$connection = mysqli_connect('localhost','root','','rest_api');
Langkah-langkah: Membuat Web Service
• Mengidentifikasi request dari consumer (client): Apa metode HTTP yang digunakan?
$request_method = $_SERVER["REQUEST_METHOD"]; switch($request_method) {
case 'GET’: //jika metode HTTP GET, ngapain?
case 'POST’: // Metode POST, untuk menambahkan produk baru (Insert)
case 'PUT’: // Metode PUT, client ingin mengupdate produk tertentu
case 'DELETE’: // Metode DELETE, client iningin menghapus produk tertentu
default: // Jika bukan salah satu dari 4 metode di atas
}
Langkah-langkah: Membuat Web Service
• Jika GET
// Metode GET, client hanya ingin meretrieve produk // dengan product_id tertentu? if(!empty($_GET["product_id"])) {
$product_id = intval($_GET["product_id"]); get_products($product_id);
} //jika tidak dengan product_id, berarti semua produk else {
get_products(); } break;
Fungsi get_products()?
Fungsi get_products()
function get_products($product_id=0) {
global $connection;
//query mengambil semua produk
$query = "SELECT * FROM products";
//hanya mengambil satu produk sesuai product_id
if($product_id ! = 0) { $query .= " WHERE id = " . $product_id . " LIMIT 1"; }
$response = array();
$result = mysqli_query($connection, $query);
while($row = mysqli_fetch_array($result)) { $response[] = $row; }
//respon untuk client dalam format JSON
header('Content-Type: application/json');
echo json_encode($response);
}
Langkah-langkah: Membuat Web Service
Jika POST, PUT dan DELETE?
//Metode POST untuk menambahkan produk baru (Insert) insert_product(); break; 6
//Metode PUT untuk mengupdate produk tertentu $product_id = intval($_GET["product_id"]); update_product($product_id); break;
//Metode DELETE untuk menghapus produk tertentu $product_id = intval($_GET["product_id"]); delete_product($product_id); break;
Langkah-langkah: Membuat Web Service
• Bagaimana fungsi:
• insert_product()
• update_product()
• delete_product()
• Lihat naskah tutorial!
Insert_product()
function insert_product() { global $connection; $product_name = $_POST["product_name"]; $price = $_POST["price"]; $quantity = $_POST["quantity"]; $seller = $_POST["seller"]; $query = ”INSERT INTO products SET product_name = '{$product_name}’, “ .
“price = {$price}, quantity = {$quantity}, seller = '{$seller}'”; if(mysqli_query($connection, $query)) { $response = array(
'status' => 1, 'status_message' =>'Produk berhasil ditambahkan.'); } else { $response = array(
'status' => 0, 'status_message' =>'Produk GAGAL ditambahkan.'); } header('Content-Type: application/json'); echo json_encode($response);
}
update_product()
function update_product($product_id) { global $connection; parse_str(file_get_contents("php://input"), $post_vars); $product_name = $post_vars["product_name"]; $price = $post_vars["price"];$quantity = $post_vars["quantity"]; $seller = $post_vars["seller"]; $query = “UPDATE products SET product_name = '{$product_name}',”
. “ price = {$price}, quantity = {$quantity}, “
. “ seller = '{$seller}' WHERE id = ” . $product_id; if(mysqli_query($connection, $query)) { $response = array(
'status' => 1, 'status_message' =>'Produk berhasil diupdate.'); } else { $response = array(
'status' => 0, 'status_message' =>'Produk GAGAL diupdate.'); } header('Content-Type: application/json'); echo json_encode($response);
}
delete_product()
function delete_product($product_id) { global $connection; $query = "DELETE FROM products WHERE id = ".$product_id;
if(mysqli_query($connection, $query)) { $response=array(
'status' => 1, 'status_message' => 'Produk berhasil dihapus.' ); } else { $response = array(
'status' => 0, 'status_message' => 'Produk GAGAL dihapus.' ); } header('Content-Type: application/json'); echo json_encode($response);
}
Menjalankan Web Service: Hanya PHP
• Buka console atau Terminal
• Masuk ke folder dimana file web service berada:cd \xampp\htdocs\produk
• Jalankan server web development dari PHP:php -S localhost:8000 products.php
PHP 7.2.2 Development Server started at Tue Apr 17 09:56:03 2018
Listening on http://localhost:8000
Document root is C:\xampp\htdocs\produk
Press Ctrl-C to quit.
.htaccess: Menulis Ulang URL
• Akses via Web browser:• GET semua produk: http://localhost:8000/products
• GET produk tertentu: http://localhost:8000/products?product_id=1
• Bagaimana agar menjadi? http://localhost:8000/products/1
• Buat file .htaccess seperti berikut:RewriteEngine On # Turn on the rewriting engine
RewriteRule ^products/?$ products.php [NC,L]
RewriteRule ^products/([0-9]+)/?$ products.php?product_id=$1 [NC,L]
Bagaimana Server Web Apache?
• Apache mempunyai fitur lebih banyak: Virtual Host berbasis Nama
• Jalankan Apache via XAMPP Control Panel
• File-file konfigurasi Virtual host• C:/xampp/apache/conf/extra/httpd-vhosts.conf
• C:\Windows\System32\drivers\etc\hosts127.0.0.1 sister
• Akses via Web browser:• GET semua produk: http://sister/products• GET produk tertentu: http:// sister/products?product_id=1
<VirtualHost *:80>
DocumentRoot "c:/xampp/htdocs/produk"
ServerName sister
</VirtualHost>
C:/xampp/apache/conf/extra/httpd-vhosts.conf
• VirtualHost: Banyak web server menggunakan port 80 sebagai port defaultnya. Namun kita dapat mengubahnya ke port 8080, 8081 dll.
• DocumentRoot: Folder dimana file-file situs akan diletakkan. Misalnya “produk”.
• ServerName: URL bagi virtual host.
• Directory: directory dari virtual host.
<VirtualHost *:80>DocumentRoot "c:/xampp/htdocs/produk"ServerName sister
</VirtualHost>
Menguji RESTful API
• Metode GET: cukup via web browser standard
• Metode POST, PUT dan DELETE: harus via web software yang mendukung metode HTTP• Salah satu: Google Postman
• Membuat client sendiri: • HTTP/2 Client di Java
• PHP menggunakan cURL
Postman Demo: GET
Postman Demo: POST
Postman Demo: PUT
Postman Demo: DELETE
Membuat Client dengan PHP (cURL)
• Membangun koneksi ke provider : curl_init()
• Menambahkan data request : curl_setopt()
• Mengirimkan request : curl_exec()
• Menutup koneksi : curl_close()
PHP cURL: Meminta Semua Produk
$url = 'http://localhost:8000products'; $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPGET, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response_json = curl_exec($ch); curl_close($ch); $response = json_decode($response_json, true);
PHP cURL: Meminta Produk Tertentu
$url = 'http://sister/products/5';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response_json = curl_exec($ch);
curl_close($ch);
$response = json_decode($response_json, true);
PHP cURL: Menambahkan Produk Baru
$data = array( 'product_name' => 'Television’,
'price' => 1000, 'quantity' => 10,
'seller' => 'XYZ Traders' );
$url = 'http://sister/products';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response_json = curl_exec($ch);
curl_close($ch);
$response=json_decode($response_json, true);
PHP cURL: Mengupdate Produk Tertentu
$data = array( 'product_name' => 'Laptop’, 'price' => 1200, 'quantity' => 15, 'seller' => 'ABC Trading Inc.' );
$url = 'http://example.com/api/products/3'; $ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response_json = curl_exec($ch); curl_close($ch);
$response=json_decode($response_json, true);
PHP cURL: Menghapus Produk Tertentu
$url = 'http://sister/products/7'; $ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response_json = curl_exec($ch); curl_close($ch);
$response=json_decode($response_json, true);
Membangun RESTful Web Service dengan Framework Slim
https://www.slimframework.com/
• Download Composer (https://getcomposer.org) dan install
• Instalasi Slim:• Buka Terminal, masuk ke htdocs
composer create-project slim/slim-skeleton [nama_app]
• Misal:composer create-project slim/slim-skeleton slim_api -vvv
• Slim_api adalah nama direktori proyek yang akan dibuat. • argumen -vvv berfungsi untuk menampilkan detail proses instalasi
• Masuk ke folder web service via Console, jalankan Web Server PHP (atau Apache):
php –S localhost:8080 –t index.php
• Atau gunakan perintah composer start
Slim Berjalan? http://localhost:8080
Membuat Database
• Buat database bernama “db_koleksi_buku”
• Setelah itu buat tabel tb_buku dengan 5 field: • Id_buku untuk menyimpan id buku;
• Judul untuk menyimpan judul buku;
• Penulis untuk menyimpan nama pengarang;
• Sinopsis untuk menyimpan teks sinopsis;
• Cover untuk menyimpan nama file sampul buku
Kode SQL: Membuat Tabel books
CREATE TABLE books (
book_id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
author VARCHAR(255) NOT NULL,
sinopsis TEXT NOT NULL,
cover VARCHAR(255) NOT NULL DEFAULT 'default_cover.png',
PRIMARY KEY (`book_id`)
) ENGINE = InnoDB;
Kode SQL: Membuat Tabel api_users
• Selanjutnya buat tabel api_users dengan field: • email untuk menyimpan email user. Email bersifat unik, jadi 1 API key hanya dimiliki
oleh satu user. • api_key untuk menyimpan API key user. API Key bersifat unik. • hit untuk menyimpan berapa kali api diakses oleh user. Biasanya digunakan untuk
membatasi akses.
CREATE TABLE api_users (
email VARCHAR(255) NOT NULL, api_key VARCHAR(255) NOT NULL, hit INT NOT NULL, PRIMARY KEY (`email`), UNIQUE (`api_key`)
) ENGINE = InnoDB;
Masukkan Data Contoh
• INSERT INTO `api_users` (`email`, `api_key`, `hit`) VALUES ('[email protected]', '123', '0');
• INSERT INTO `books` (`book_id`, `title`, `author`, `sinopsis`, `cover`) VALUES (NULL, 'Belajar Pemrograman PHP dari Nol Hingga Mahir', 'Muhar Dian', 'Buku ini membahas tentang tutorial step by step pemrograman php dari awal hingga membuat aplikasi web.', 'default_cover.png');
File Penting
• Selama pengembangan RESTful API menggunakan Slim, ada 4 file utama yang akan dikonfigurasi atau diprogram
• Semuanya di dalam C:\xampp\htdocs\slim_api\src• dependencies.php :
• middleware.php :
• routes.php : penentuan rute
• settings.php : konfigurasi database, dll
Konfigurasi Koneksi Database: src/settings.php
// Database Settings 'db' => [
'host' => 'localhost', 'user' => 'root', 'pass' => ‘’, 'dbname' => ‘db_koleksi_buku', 'driver' => 'mysql'
]
Container Database: src/depedencies.php
// database
$container['db'] = function ($c){
$settings = $c->get('settings')['db'];
$server = $settings['driver'].":host=".$settings['host'].";dbname=".$settings['dbname'];
$conn = new PDO($server, $settings["user"], $settings["pass"]);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $conn;
};
Membuat Rute
Rute Metode Parameter Keterangan
/books/ GET key Untuk mengambil semua buku
/books/1 GET key Menampilkan 1 buku berdasarkan id
/books/search GET key, keyword Untuk mencari buku
/books POST key Untuk menambahkan buku baru
/books/1 PUT key Untuk mengedit data buku
/books/1 DELETE key Untuk menghapus buku
Contoh: /books/search?key=123&keyword=bukuphp
Rute pertama ke dalam src/routes.php
• Rute GET /books/, mengambil semua buku - URL: http://localhost:8080/books/
$app->get("/books/", function (Request $request, Response $response){
$sql = "SELECT * FROM tb_buku";
$stmt = $this->db->prepare($sql);
$stmt->execute()
$result = $stmt->fetchAll();
return $response->withJson(["status" => "success",
"data" => $result], 200);
});
Rute GET /books/1
$app->get("/books/{id}",
function (Request $request, Response $response, $args){
$id = $args["id"];
$sql = "SELECT * FROM tb_buku WHERE book_id=:id";
$stmt = $this->db->prepare($sql);
$stmt->execute([":id" => $id]);
$result = $stmt->fetch();
return $response->withJson(["status" => "success",
"data" => $result], 200);
});
Rute GET /books/search
Rute untuk pencarian buku berdasarkan judul, sinopsis, dan nama penulis
$app->get("/books/search/",
function (Request $request, Response $response, $args){
$keyword = $request->getQueryParam("keyword");
$sql = "SELECT * FROM books WHERE title LIKE '%$keyword%' OR sinopsis LIKE '%$keyword%' OR author LIKE '%$keyword%'";
$stmt = $this->db->prepare($sql);
$stmt->execute([":id" => $id]);
$result = $stmt->fetchAll();
return $response->withJson(["status" => "success",
"data" => $result], 200);
});
Rute POST /books
Rute ini diakses dengan metode POST. Rute ini untuk menambah data buku baru
$app->post("/books/", function (Request $request, Response $response){ $new_book = $request->getParsedBody(); $sql = "INSERT INTO books (title, author, sinopsis) VALUE (:title, :author, :sinopsis)"; $stmt = $this->db->prepare($sql); $data = [
":title" => $new_book["title"], ":author" => $new_book["author"], ":sinopsis" => $new_book["sinopsis"]
];if($stmt->execute($data)) return $response->withJson(["status" => "success", "data" => "1"], 200); return $response->withJson(["status" => "failed", "data" => "0"], 200);
});
Rute PUT /books/1
Rute ini bertugas untuk mengubah data buku berdasarkan ID.
$app->put("/books/{id}", function (Request $request, Response $response, $args){
$id = $args["id"];
$new_book = $request->getParsedBody();
$sql = "UPDATE books SET title=:title, author=:author,
sinopsis=:sinopsis WHERE book_id=:id";
$stmt = $this->db->prepare($sql);
$data = [
":id" => $id,
":title" => $new_book["title"],
":author" => $new_book["author"],
":sinopsis" => $new_book["sinopsis"]
];
if($stmt->execute($data))
return $response->withJson(["status" => "success", "data" => "1"], 200);
return $response->withJson(["status" => "failed", "data" => "0"], 200);
});
Rute DELETE /books/1
$app->delete("/books/{id}",
function (Request $request, Response $response, $args){
$id = $args["id"];
$sql = "DELETE FROM books WHERE book_id=:id";
$stmt = $this->db->prepare($sql);
$data = [":id" => $id];
if($stmt->execute($data))
return $response->withJson(["status" => "success", "data" => "1"], 200);
return $response->withJson(["status" => "failed", "data" => "0"], 200);
});
Middleware untuk Validasi API Key
Middleware
• Fungsi yang akan dieksekusi di setiap ada request yang masuk ke aplikasi.
• Middleware biasanya digunakan untuk validasi Key dari API, membuat login, mencatat logs, dan lain-lain.
src/middleware.php <?php
// Application middleware
// e.g: $app->add(new \Slim\Csrf\Guard);
// middleware untuk validasi api key
$app->add(function ($request, $response, $next) {
$key = $request->getQueryParam("key");
if(!isset($key)){ return $response->withJson(["status" => "API Key required"], 401); }
$sql = "SELECT * FROM api_users WHERE api_key=:api_key";
$stmt = $this->db->prepare($sql);
$stmt->execute([":api_key" => $key]);
if($stmt->rowCount() > 0){
$result = $stmt->fetch();
if($key == $result["api_key"]){
// update hit
$sql = "UPDATE api_users SET hit=hit+1 WHERE api_key=:api_key";
$stmt = $this->db->prepare($sql);
$stmt->execute([":api_key" => $key]);
return $response = $next($request, $response);
}
}
return $response->withJson(["status" => "Unauthorized"], 401);
});
Maksud dari kode tersebut
• Cek parameter key;
• Ambil data di database berdasarkan parameter key;
• Bandingkan parameter key dengan api_key yang tersimpan di database;
• Jika benar, tampilkan data yang diminta dan tambahkan hit.
Akses http://localhost:8080,
• Aplikasi meminta API Key.
Tambahkan Parameter ?key=123.
Bila API key-nya salah?
Middleware Selektif
• Menuliskan middleware seperti sebelumnya, mengakibatkan semua rute membutuhkan API Key.
• Jika diinginkan pengecekan API key hanya pada rute tertentu, maka harus ditambahkan middleware pada rute tersebut.
• Contoh: // membuat middleware $cekAPIKey = function($request, $response, $next){ // ini middleware untuk cek apikey }
// menambahkan middleware ke route $app->get('/books', function ($request, $response) { // ... })->add(cekAPIKey());
Pengelompokan Rute
• Middleware dapat pula ditambahkan ke route group.
• Contoh:
$app->group('/api', function () use ($app) {
$app->get('/books', function ($request, $response) {
// ...
});
$app->get('/books/{id}', function ($request, $response) {
// ...
});
})->add(cekAPIKey());
Uji Coba Aplikasi dengan Postman
• Slim akan otomatis mengubahnya menjadi array asosiatif, karena itu digunakan fungsi $this->getParsedBody() untuk mengambilnya.
Contoh RESTful APILogin dan Register Berbasis Session
Persiapan
• Buat folder bernama restapi
• Masuk ke folder restapi tersebut dan install Slim:composer require slim/slim “^3.0”
• Buat folder example, tempat kita menempatkan 6 file berikut:• login.php • delete.php • index.php • edit.php • register.php • logout.php
• Folder example digunakan untuk memanggil layanan REST API (sisi consumer/client dari RESTful Web Service)
login.php
<?php session_start(); ?>
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<h3>Simple example how to create rest api and use http method with slim framework by
seegatesite.com</h3>
<h2>GET METHOD</h2>
<form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?> ">
<table>
<tr>
<td>Email :</td>
<td><input type="email" name="email"></td>
</tr>
<tr>
<td>Password :</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" name="submit" value="login"></td>
</tr>
</table>
</form>
A new user ? <a href="register.php">register</a>
<?php
if(isset($_POST['submit'])) {
if (!empty($_POST['email']) and !empty($_POST['password'])) {
$email = $_POST['email'];
$password = $_POST['password'];
$ch =
curl_init('http://localhost/restapi/api/get/login/'.$email.'/'.$password)
;
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
($ch);
curl_close($ch);
$data = json_decode($response,true);
if($data['data']['islogin'] == true) {
$_SESSION['email'] = $data['data']['email'];
$_SESSION['password'] = $data['data']['password'];
$_SESSION['name'] = $data['data']['name'];
$_SESSION['country'] = $data['data']['country'];
header("location:index.php");
} else {
echo '
<hr />
'.$data['message'];
}
}else {
echo 'Please fill the Email or Password ';
}
}
?>
</body>
</html>
Deskripsi : Halaman login akan mengimplementasikan PHP curl untuk mengajukan requests dengan metode GET.
register.php <!DOCTYPE html>
<html>
<head>
<title>Register Page</title>
</head>
<body>
<h3>Menu Register</h3>
<h2>POST METHOD</h2>
<form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?> " >
<table>
<tr> <td>Email :</td> <td><input type="email" name="email"></td> </tr>
<tr> <td>Password :</td> <td><input type="password" name="password"></td> </tr>
<tr> <td>Name :</td> <td><input type="text" name="name"></td> </tr>
<tr> <td>Country :</td> <td><input type="text" name="country"></td> </tr>
<tr> <td><input type="submit" name="submit" value="Register"></td> </tr>
</table>
</form>
You need login? <a href="login.php">Login page</a>
<?php if(isset($_POST['submit'])) {
if (!empty($_POST['email']) and !empty($_POST['password’]) and
!empty($_POST['name']) and !empty($_POST['country'])) {
$email = $_POST['email']; $password = $_POST['password’];
$name = $_POST['name']; $country = $_POST['country’];
$post = array('email' => $email, 'password' => $password,
'name' => $name, 'country' => $country);
$data = json_encode($post);
$ch = curl_init('http://localhost/restapi/api/post/register');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response,true);
echo '<hr /> '.$data['message'];
} else { echo 'Please fill Data '; }
}
?>
</body>
</html>
Deskripsi: Halaman register akan mengimplementasikan PHP curl untuk membuat make requests dengan metode POST.
index.php <?php
session_start();
if(!isset($_SESSION['email'])) { header("location:login.php"); }
?>
<!DOCTYPE html>
<html><head><title>Welcome home </title></head>
<body>
Welcome to Home <a href="logout.php">Logout</a>
<hr>
<table>
<tr> <td> Name : </td> <td> <?php echo $_SESSION['name']; ?> </td> </tr>
<tr> <td> Email : </td> <td> <?php echo $_SESSION['email']; ?> </td> </tr>
<tr> <td> country : </td> <td> <?php echo $_SESSION['country']; ?> </td> </tr>
<tr> <td> <a href="edit.php">Edit</a> <a href="delete.php">Delete</a> </td> </tr>
</table>
</body>
</html>
edit.php <?php session_start(); if(!isset($_SESSION['email'])) { header("location:login.php"); } ?>
<!DOCTYPE html>
<html>
<head>
<title>Edit Page</title>
</head>
<body>
<?php if(isset($_POST['submit'])) { if ( !empty($_POST['password']) and !empty($_POST['name']) and
!empty($_POST['country'])) { $email = $_POST['email']; $password = $_POST['password']; $name =
$_POST['name']; $country = $_POST['country']; $post = array( 'password' => $password, 'name' => $name,
'country' => $country);
$data = json_encode($post);
$ch = curl_init('http://localhost/restapi/api/put/edit/'.$email);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response,true);
echo '<hr /> '.$data['message'];
Deskripsi: Halaman edit akan mengimplementasikan PHP curl untuk membuat requests dengan metode PUT.
$_SESSION['email'] = $data['data']['email'];
$_SESSION['password'] = $data['data']['password'];
$_SESSION['name'] = $data['data']['name'];
$_SESSION['country'] = $data['data']['country'];
echo '<hr/><a href="index.php">Back to dashboard</a>';
}else {
echo 'Please fill Data ';
}
}
?>
<h1>PUT METHOD</h1>
<form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?> " >
<table>
<tr>
<td>Email :</td>
<td><input type="email" readonly value="<?php echo $_SESSION['email'] ?>" name="email"></td>
</tr>
<tr><td>Password :</td>
<td><input type="password" value="<?php echo $_SESSION['password'] ?>"
name="password"></td>
</tr>
<tr><td>Name :</td>
<td><input type="text" value="<?php echo $_SESSION['name'] ?>"
name="name"></td>
</tr>
<tr><td>Country :</td>
<td><input type="text" value="<?php echo $_SESSION['country'] ?>"
name="country"></td>
</tr>
<tr><td><input type="submit" name="submit" value="Edit"></td></tr>
</table>
</form>
</body>
</html>
delete.php
<?php session_start(); if(!isset($_SESSION['email'])) { header("location:login.php"); } ?>
<!DOCTYPE html>
<html>
<head> <title>delete Page</title> </head>
<body>
<h1>DELETE METHOD</h1>
<form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?> " >
<table>
<tr><td>Email :</td><td><input type="email" readonly value="<?php echo $_SESSION['email'] ?>"
name="email"></td></tr>
<tr><td>Password :</td><td><input type="password" value="<?php echo $_SESSION['password'] ?>"
name="password"></td></tr>
<tr><td>Name :</td><td><input type="text" value="<?php echo $_SESSION['name'] ?>"
name="name"></td></tr>
<tr><td>Country :</td><td><input type="text" value="<?php echo $_SESSION['country'] ?>"
name="country"></td></tr>
<tr><td><input type="submit" name="submit" value="Delete this account ?"></td></tr>
</table>
</form>
Deskripsi: Halaman delete akan mengimplementasikan PHP curl untuk membuat requests dengan metode DELETE.
<?php
if(isset($_POST['submit'])) {
$email = $_SESSION['email’];
$ch = curl_init('http://localhost/restapi/api/delete’);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response,true);
print_r($data);
if($data['status'] == 200) {
header("location:logout.php");
} else { echo 'error : '.json_decode($response); }
}
?>
</body>
</html>
logout.php
<?php session_start(); unset($_SESSION['email']); unset($_SESSION['password']); unset($_SESSION['name']); unset($_SESSION['country']); header("location:login.php");
?>
RESTful API (router.php): Lengkap
$app->delete('/delete', function($request, $response,$args) {
if(file_exists('data.json')) {
unlink("data.json");
}
$array['status'] = '200';
$array['message'] = 'delete success';
$array['data'] = array("islogin"=>false);
return $response->withStatus(200)
->withHeader("Content-Type","application/json")
->write(json_encode($array));
});
$app->get('/get/login/{email}/{password}', function($request, $response,$args) {
$email = $args['email'];
$password =$args['password'];
if(file_exists('data.json')) {
$datajson = json_decode(file_get_contents('data.json'), true);
foreach ($datajson as $key) {
$data['email'] = $key['email']; $data['password'] = $key['password'];
$data['name'] = $key['name’]; $data['country'] = $key['country'];
}
}else { $data['email'] = ‘’; $data['password'] = ‘’;
$data['name'] = ‘’; $data['country'] = '';
}
if($email == $data['email'] and $password == $data['password’]) {
$array['status'] = '200’; $array['message'] = 'login success';
$array['data'] = array("islogin"=>true, "name"=>$data['name’], "country"=>$data['country’],
"email"=>$data['email'], password"=>$data['password']);
} else { $array['status'] = '401’; $array['message'] = 'Unauthorized User’;
$array['data']= array("islogin"=>false,"name"=>$data['email'],"country"=>'');
}
return $response->withStatus(200)
->withHeader("Content-Type","application/json")
->write(json_encode($array));
});
GET /get/login/{email}/{password}
POST/post/register
$app->post('/post/register', function($request, $response){
$datajson = array();
$data = json_decode($request->getBody(),true);
$datajson[] = $data;
$fp = fopen('data.json', 'w');
fwrite($fp, json_encode($datajson));
fclose($fp);
$array['status'] = '200';
$array['message'] = 'register success';
$array['data’] = array("islogin"=>false);
return $response->withStatus(200)
->withHeader("Content-Type","application/json")
->write(json_encode($array));
});
PUT/put/edit/{email}
$app->put('/put/edit/{email}', function($request, $response,$args){
$email = $args['email'];
$datajson = array();
$data = json_decode($request->getBody(),true);
$data['email'] = $email;
$datajson[] = $data;
$fp = fopen('data.json', 'w');
fwrite($fp, json_encode($datajson));
fclose($fp);
$array['status'] = '200';
$array['message'] = 'Edit Success';
$array['data'] = array("islogin"=>true, "name"=>$data['name'],
"country"=>$data['country'], "email"=>$data['email'],
"password"=>$data['password']);
return $response->withStatus(200)
->withHeader("Content-Type","application/json")
->write(json_encode($array));
});
$app->run();
• Deskripsi: Untuk menjawab request dalam format json pada Slim Framework menggunakan fungsi-fungsi berikut:
return $response->withStatus(200) ->withHeader("Content-Type","application/json") ->write(json_encode($array));
404
• Handler jika request tidak ditemukan (404), menggunakan fungsi berikut:
$c['notFoundHandler'] = function ($c) { return function ($request, $response) use ($c) {
$array = array('Status'=>'404','Message'=>'Page not found'); return $c['response’]
->withStatus(404) ->withHeader("Content-Type","application/json") ->write(json_encode($array));
}; };
.htaccess
• Deskripsi: Skrip di atas digunakan untuk membuat link yang lebih baik.
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [QSA,L]