API Sample now supports minimal GET, POST, PUT, and DELETE actions.

This commit is contained in:
PJ Dietz 2012-12-05 15:35:23 -05:00
parent e910418ab1
commit ff331935d2
5 changed files with 404 additions and 6 deletions

View File

@ -0,0 +1,28 @@
The apisample directory contains a mini API project that demonstrates all of the
main features of Well RESTEd.
/articles/
Represents a list of articles.
GET
Displays a list of articles
POST
Add a new article
PUT
Not allowed
DELETE
Not allowed
/articles/{id}
/articles/{slug}
Represents one specific article identified by the numberic ID {id} or by the
alpha-numeric slug.
GET
Displays one specific article
POST
Not allowed
PUT
Replace the article with the given contents
DELETE
Remove the article

View File

@ -0,0 +1,115 @@
<?php
class ArticlesControler {
public $data;
protected $path;
public function __construct() {
$this->path = dirname(__FILE__) . '/articles.json';
$this->load();
}
public function load() {
if (file_exists($this->path)) {
$data = file_get_contents($this->path);
$this->data = json_decode($data, true);
}
}
public function save() {
if (is_writable($this->path)) {
$data = json_encode($this->data);
return file_put_contents($this->path, $data);
}
return false;
}
public function getArticleById($id) {
foreach ($this->data as $article) {
if ($article['articleId'] == $id) {
return $article;
}
}
return false;
}
public function getArticleBySlug($slug) {
foreach ($this->data as $article) {
if ($article['slug'] == $slug) {
return $article;
}
}
return false;
}
public function addArticle($newArticle) {
$validatedArticle = array(
'articleId' => $this->getNewId(),
'slug' => $newArticle['slug'],
'title' => $newArticle['title'],
'excerpt' => $newArticle['excerpt']
);
$this->data[] = $validatedArticle;
return $validatedArticle;
}
public function updateArticle($newArticle) {
foreach ($this->data as &$oldArticle) {
if ($oldArticle['articleId'] == $newArticle['articleId']) {
$oldArticle['slug'] = $newArticle['slug'];
$oldArticle['title'] = $newArticle['title'];
$oldArticle['excerpt'] = $newArticle['excerpt'];
return $newArticle;
}
}
return false;
}
public function removeArticle($id) {
foreach ($this->data as $index => $article) {
if ($article['articleId'] == $id) {
unset($this->data[$index]);
return true;
}
}
return false;
}
protected function getNewId() {
$maxId = 0;
foreach ($this->data as $article) {
$maxId = max($maxId, $article['articleId']);
}
return $maxId + 1;
}
}
?>

View File

@ -0,0 +1,11 @@
[{
"articleId": 1,
"slug": "good-movie",
"title": "Reports Of Movie Being Good Reach Area Man",
"excerpt": "Local resident Daniel Paxson has reportedly heard dozens of accounts from numerous friendly sources in the past two weeks confirming that the new James Bond film is pretty good. According to persons with knowledge of the situation, an unnamed friend of Paxsons coworker Wendy Mathers watched the movie on opening weekend and found it to be “decent enough.”"
}, {
"articleId": 2,
"slug": "species-protection",
"title": "Endangered Wildlife To Be Given New Identities In Species Protection Program",
"excerpt": "In an effort to protect at-risk animals from those who might wish to do them harm, the U.S. Fish and Wildlife Service announced Friday it had launched a program that provides endangered species with new names and habitats to ensure their anonymity."
}]

View File

@ -3,14 +3,90 @@
namespace handlers;
require_once(dirname(__FILE__) . '/../../../Handler.inc.php');
require_once(dirname(__FILE__) . '/../data/ArticlesControler.inc.php');
class ArticleCollectionHandler extends \wellrested\Handler {
protected function get() {
$this->response->statusCode = 200;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'A list of articles.';
// Display the list of articles.
$articles = new \ArticlesControler();
if (isset($articles->data)) {
$this->response->statusCode = 200;
$this->response->setHeader('Content-type', 'application/json');
$this->response->body = json_encode($articles->data);
} else {
$this->response->statusCode = 500;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to read the articles.';
}
}
protected function post() {
// Read the request body, and ensure it is in the proper format.
$article = json_decode($this->request->body, true);
// Ensure the JSON is well-formed.
if (!$article) {
$this->response->statusCode = 400;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to parse JSON from request body.';
return;
}
// Ensure requied fields are present.
if (!isset($article['slug']) || $article['slug'] === '') {
$this->response->statusCode = 400;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Request body missing slug.';
return;
}
if (!isset($article['title'])) {
$this->response->statusCode = 400;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Request body missing title.';
return;
}
if (!isset($article['excerpt'])) {
$this->response->statusCode = 400;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Request body missing excerpt.';
return;
}
// Ensure slug is not a duplicate.
$articles = new \ArticlesControler();
if ($articles->getArticleBySlug($article['slug']) !== false) {
$this->response->statusCode = 409;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to store article. Slug "' . $article['slug'] . '" is already in use.';
return;
}
// All looks good! Add this to the articles and save!
$article = $articles->addArticle($article);
if ($articles->save() === false) {
$this->response->statusCode = 500;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to write to file. Make sure permissions are set properly.';
return;
}
// Ok!
$this->response->statusCode = 201;
$this->response->setHeader('Content-type', 'application/json');
$this->response->body = json_encode($article);
return;
}

View File

@ -3,15 +3,183 @@
namespace handlers;
require_once(dirname(__FILE__) . '/../../../Handler.inc.php');
require_once(dirname(__FILE__) . '/../data/ArticlesControler.inc.php');
class ArticleItemHandler extends \wellrested\Handler {
protected function get() {
// Read the list of articles.
$articles = new \ArticlesControler();
$article = false;
// Locate the article by ID or slug
if (isset($articles->data)) {
if (isset($this->args['id'])) {
$article = $articles->getArticleById($this->args['id']);
} elseif (isset($this->args['slug'])) {
$article = $articles->getArticleBySlug($this->args['slug']);
}
}
if ($article !== false) {
$this->response->statusCode = 200;
$this->response->setHeader('Content-type', 'application/json');
$this->response->body = json_encode($article);
} else {
$this->response->statusCode = 404;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to locate the article.';
}
}
protected function put() {
// Read the request body, and ensure it is in the proper format.
$article = json_decode($this->request->body, true);
// Ensure the JSON is well-formed.
if (!$article) {
$this->response->statusCode = 400;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to parse JSON from request body.';
return;
}
// Ensure required fields are present.
if (!isset($article['slug']) || $article['slug'] === '') {
$this->response->statusCode = 400;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Request body missing slug.';
return;
}
if (!isset($article['title'])) {
$this->response->statusCode = 400;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Request body missing title.';
return;
}
if (!isset($article['excerpt'])) {
$this->response->statusCode = 400;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Request body missing excerpt.';
return;
}
// Read the list of articles.
$articles = new \ArticlesControler();
$oldArticle = false;
// Locate the article by ID or slug
if (isset($articles->data)) {
if (isset($this->args['id'])) {
$oldArticle = $articles->getArticleById($this->args['id']);
} elseif (isset($this->args['slug'])) {
$oldArticle = $articles->getArticleBySlug($this->args['slug']);
}
}
// Fail if the article identified by the URI does not exist.
if ($oldArticle === false) {
$this->response->statusCode = 404;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to locate the article.';
return;
}
// If the user located the resource by ID and has passed a slug,
// make sure the new slug is not already in use.
if (isset($this->args['id'])) {
$slugArticle = $articles->getArticleBySlug($article['slug']);
if ($slugArticle && $slugArticle['articleId'] != $article['articleId']) {
$this->response->statusCode = 409;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to store article. Slug "' . $article['slug'] . '" is already in use.';
return;
}
}
// Update the article.
// First, ensure the articleId is set.
// It must match the existing article found earlier.
$article['articleId'] = $oldArticle['articleId'];
// Keep the results from the update for the response.
$article = $articles->updateArticle($article);
if ($articles->save() === false) {
$this->response->statusCode = 500;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to write to file. Make sure permissions are set properly.';
return;
}
// Ok!
$this->response->statusCode = 200;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'One article';
$this->response->body = print_r($this->args, true);
$this->response->setHeader('Content-type', 'application/json');
$this->response->body = json_encode($article);
return;
}
protected function delete() {
// Read the list of articles.
$articles = new \ArticlesControler();
$article = false;
// Locate the article by ID or slug
if (isset($articles->data)) {
if (isset($this->args['id'])) {
$article = $articles->getArticleById($this->args['id']);
} elseif (isset($this->args['slug'])) {
$article = $articles->getArticleBySlug($this->args['slug']);
}
}
// Ensure the article exists.
if ($article === false) {
$this->response->statusCode = 404;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to locate the article.';
return;
}
// Remove the article and save.
$articles->removeArticle($article['articleId']);
if ($articles->save() === false) {
$this->response->statusCode = 500;
$this->response->setHeader('Content-type', 'text/plain');
$this->response->body = 'Unable to write to file. Make sure permissions are set properly.';
return;
}
// Ok!
$this->response->statusCode = 200;
return;
}