0% found this document useful (0 votes)
55 views

7 - PHP MVC Frameworks REST Controllers and Routing Lab

This document provides steps to create a REST API for a blog application using Symfony, including installing the JMSSerializerBundle, creating an Article entity, setting up the database, and creating REST controllers with actions for getting a list of articles, getting a single article, creating a new article, deleting an article, and editing an article.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
55 views

7 - PHP MVC Frameworks REST Controllers and Routing Lab

This document provides steps to create a REST API for a blog application using Symfony, including installing the JMSSerializerBundle, creating an Article entity, setting up the database, and creating REST controllers with actions for getting a list of articles, getting a single article, creating a new article, deleting an article, and editing an article.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

REST Controllers, Routing, JSON

Responses
This document defines a complete walkthrough of creating a REST API for our Blog application,
from setting up the serializer bundle, creating our own API bundle, ending up with fully
functioning REST API.

Create the Project


Open terminal and go to the directory of your project
In terminal, type following command: symfony new BlogRestApi

symfony new --full BlogRestApi

Install serialization bundle


For the purpose of this exercise we need functionality which serialize/deserialize our Doctrine
entities to JSON and vice versa – JMSSerializerBundle
Open terminal / console and go to the directory of your project. If you still don’t have Composer
you can download it from here: http://getcomposer.org
In terminal / cmd type following command: composer require jms/serializer-bundle

composer require jms/serializer-bundle

The command will download the bundle and include it automatically to the autoloader. You don’t
need to include anything anywhere.

Create the Article Entity


Open Terminal or Command Prompt (CMD) in the blog project root folder. Let’s model our
articles. That means that we are going to create the defining properties of an article. To do that,
we need to generate a Doctrine Entity. Our entity will describe what are we going to store in our
database. The following command will start entity generator wizard:

php bin/console make:entity

You should see this result:

PROJECT WEB - WEBG301 1


Our first field will be the “Title” of our article. Just write “title” and press ‘Enter’.
Press ‘Enter’. You should see “Field length [255]”. Press ‘Enter’ again. You will be asked if
you want to make the field nullable. Press ‘Enter’. Finally, you will be asked to make your field
unique. Just press ‘Enter’ one more time

Similar to this, we should create 2 more fields for the “content” and “date”. Here is how we
create them:

PROJECT WEB - WEBG301 2


Update Database
Change database connection in .env file
Specific: admin, password and database name


DATABASE_URL=mysql://root:@127.0.0.1:3306/blog_rest_api?
serverVersion=mariadb-10.4.11

PROJECT WEB - WEBG301 3


Create database

php bin/console doctrine:database:create

Open phpMyAdmin, you can see the database “blog_rest_api” is created.

To perform migration, type below command:

php bin/console make:migration

You can see the migration file is created in folder migrations

To run that migration, execute command below:

php bin/console doctrine:migrations:migrate

Now, you should see the table “article” is created in the database “blog_rest_api”

PROJECT WEB - WEBG301 4


Create ArticleController

Create articlesAction() - get list of articles

class ArticleController extends AbstractController


{
// Config serializer
private $serializer;

public function __construct(SerializerInterface $serializer)


{
$this->serializer = $serializer;
}

/**
* @Route("/articles", methods={"GET"}, name="rest_api_articles")
*/
public function articlesAction()
{
// Get all articles in Database
$articles = $this->getDoctrine()->getRepository(Article::class)->findAll();

// Convert object articles to JSON


$json = $this->serializer->serialize($articles, 'json');

return new Response($json,


Response::HTTP_OK,
array('content-type' => 'application/json')
);
}

To test the first action, type the following command to run the local server:

php bin/console server:run

PROJECT WEB - WEBG301 5


Check if everything works correctly.

Create new articleAction() - get single article


/**
* @Route("/articles/{id}", methods={"GET"}, name="rest_api_article")
*/
public function articleAction($id)
{
// Get a single article from Database
$article = $this->getDoctrine()->getRepository(Article::class)->find($id);

// Article not found


if ($article == null) {
return new Response(json_encode(array('error' => 'article not found')),
Response::HTTP_NOT_FOUND,
array('content-type' => 'application/json')
);

PROJECT WEB - WEBG301 6


}

// Article found
$json = $this->serializer->serialize($article, 'json');
return new Response(
$json,
Response::HTTP_OK,
array('content-type' => 'application/json')
);
}

The code is pretty much the same as previous one with a little difference.
If requested article is not found Response object is returned containing error message encoded in
JSON
The Response code for not found resources is 404 or in Symfony
Response::HTTP_NOT_FOUND
For successful requests response code should be 200 OK .
In Symfony - Resonse::HTTP_OK
Create new action: createAction() - responsible for creating new articles
/**
* @Route("/articles/create", methods={"POST"}, name="rest_api_article_create")
*/
public function createAction(Request $request)
{
try {
// Get data in Request from client
$article = new Article();
$data = json_decode($request->getContent(), true);
$article->setTitle($data['title']);
$article->setContent($data['content']);
$article->setDate(\DateTime::createFromFormat('Y-m-d', $data['date']));

// Try to insert new article to Database


$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();

// Return OK if created successfully


return new Response(null, Response::HTTP_CREATED);
} catch (\Exception $e) {
// Return BAD_REQUEST if created unsuccessfully
return new Response(null, Response::HTTP_BAD_REQUEST);
}
}

Test to see if it works correctly

PROJECT WEB - WEBG301 7


Create new deleteAction() - delete resource
/**
* @Route("/articles/delete/{id}", methods={"DELETE"}, name="rest_api_delete")
*/
public function deleteAction($id)
{
try {
// Get id from Request and try to delete
$article = $this->getDoctrine()->getRepository(Article::class)->find($id);
if ($article == null) {
$statusCode = Response::HTTP_NOT_FOUND;
} else {
$em = $this->getDoctrine()->getManager();
$em->remove($article);
$em->flush();

$statusCode = Response::HTTP_NO_CONTENT;
}

return new Response(null, $statusCode);


} catch (\Exception $e) {
// Return BAD_REQUEST if something went wrong
return new Response(null, Response::HTTP_BAD_REQUEST);
}
}

Test to see if “delete” action works correctly

PROJECT WEB - WEBG301 8


Create new action: editAction() - edit article
/**
* @Route("/articles/edit/{id}", methods={"PUT"}, name="rest_api_edit")
*/
public function editAction(Request $request, $id)
{
// Find if article with id exsited
$article = $this->getDoctrine()->getRepository(Article::class)->find($id);
if ($article == null) {
$statusCode = Response::HTTP_NOT_FOUND;
} else {
$data = json_decode($request->getContent(), true);
$article->setTitle($data['title']);
$article->setContent($data['content']);
$article->setDate(\DateTime::createFromFormat('Y-m-d', $data['date']));

$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();

$statusCode = Response::HTTP_NO_CONTENT;
}
return new Response(null, $statusCode);
}

PROJECT WEB - WEBG301 9

You might also like