Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
421 views

19 - PHP-MVC-Frameworks-REST Api-Lab

This document discusses creating a REST API with Symfony without using FosRestBundle. It first explains what REST is and the HTTP verbs used. It then outlines steps to create a Symfony project, generate an entity class for posts, and create a PostController with routes to GET, POST, PUT, and DELETE posts from the API. Methods in the controller interact with the entity manager and repository to handle database operations when requests are made to the API endpoints.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
421 views

19 - PHP-MVC-Frameworks-REST Api-Lab

This document discusses creating a REST API with Symfony without using FosRestBundle. It first explains what REST is and the HTTP verbs used. It then outlines steps to create a Symfony project, generate an entity class for posts, and create a PostController with routes to GET, POST, PUT, and DELETE posts from the API. Methods in the controller interact with the entity manager and repository to handle database operations when requests are made to the API endpoints.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 12

Symfony REST API (without

FosRestBundle)
1- What is Rest?
Rest as Representational State transfer is an architectural style for developing web services. It is
something that can not be ignored because there is a big need for creating Restful applications in
today’s ecosystem. This might be due to the continued climb of JavaScript and these frameworks.
Rest API should use HTTP protocol. This mean that when the client makes any request to this
web service, it can specify any of the normal HTTP verbs of GET, POST, DELETE and PUT.
Below is what would happen If the respective verbs were sent by the client.
- GET: This would be used to get the list of resources or the details of one.
- POST: this would be used to create a new resource.
- PUT: This would be used to update an existing resource.
- DELETE: This would be used to delete an existing resource.
Rest is stateless and this mean that the server side doesn’t hold any request state. The state should
be kept on the client side (example of using JWT for authentication, we are going to secure our
RestApi using this). So, when using authentication in our Rest Api, we need to send the
authentication header in order to get a correct response in a stateless way.

2- Create a symfony project:


Firstly, we suppose you have installed php and the composer package manager to create a new
symfony project. After that, create a new project using the following command in the terminal:
Symfony new –full demo_rest_api –version=3.4

Here is what directory structure looks like:

PROJECT WEB - WEBG301 1


Below is the configuration of database I created which may be set in the .env file.

Now, let’s create our first entity. Create a new file called Post.php inside the src/Entity folder.
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;


use Symfony\Component\Validator\Constraints as Assert;

/**
* @ORM\Entity(repositoryClass=PostRepository::class)
* @ORM\Table(name="post")
* @ORM\HasLifecycleCallbacks()
*/
class Post implements \JsonSerializable {
/**
* @ORM\Column(type="integer")
* @ORM\Id

PROJECT WEB - WEBG301 2


* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @ORM\Column(type="string", length=100)
*
*/
private $name;
/**
* @ORM\Column(type="text")
*/
private $description;

/**
* @ORM\Column(type="datetime")
*/
private $create_date;

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return mixed
*/
public function getDescription()
{
return $this->description;
}
/**
* @param mixed $description
*/

PROJECT WEB - WEBG301 3


public function setDescription($description)
{
$this->description = $description;
}

/**
* @return mixed
*/
public function getCreateDate(): ?\DateTime
{
return $this->create_date;
}

/**
* @param \DateTime $create_date
* @return Post
*/
public function setCreateDate(\DateTime $create_date): self
{
$this->create_date = $create_date;
return $this;
}

/**
* @throws \Exception
* @ORM\PrePersist()
*/
public function beforeSave(){

$this->create_date = new \DateTime('now', new \


DateTimeZone('Africa/Casablanca'));
}

/**
* Specify data which should be serialized to JSON
* @link https://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
public function jsonSerialize()
{
return [
"name" => $this->getName(),
"description" => $this->getDescription()
];
}
}

In order to generate the repository, use the command

php bin/console make:entity --regenerate App

PROJECT WEB - WEBG301 4


Then, place the file PostRepository.php under the folder Repository

Run the command php bin/console doctrine:database:create to create the database


demo_rest_api
And after run the command: php bin/console doctrine:schema:create to create a
database table according to our Post entity.
Now, let’s create a PostController.php where we will add all methods interacting with api. It
should be placed inside the folder src/Controller.
<?php

namespace App\Controller;

use App\Entity\Post;
use App\Repository\PostRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

/**
* Class PostController
* @package App\Controller
* @Route("/api", name="post_api")
*/
class PostController extends AbstractController
{
/**
* @param PostRepository $postRepository
* @return JsonResponse
* @Route("/posts", name="posts", methods={"GET"})
*/
public function getPosts(PostRepository $postRepository){
$data = $postRepository->findAll();
return $this->response($data);
}

/**

PROJECT WEB - WEBG301 5


* @param Request $request
* @param EntityManagerInterface $entityManager
* @param PostRepository $postRepository
* @return JsonResponse
* @throws \Exception
* @Route("/posts", name="posts_add", methods={"POST"})
*/
public function addPost(Request $request, EntityManagerInterface
$entityManager, PostRepository $postRepository){

try{
$request = $this->transformJsonBody($request);

if (!$request || !$request->get('name') || !$request->request-


>get('description')){
throw new \Exception();
}

$post = new Post();


$post->setName($request->get('name'));
$post->setDescription($request->get('description'));
$entityManager->persist($post);
$entityManager->flush();

$data = [
'status' => 200,
'success' => "Post added successfully",
];
return $this->response($data);

}catch (\Exception $e){


$data = [
'status' => 422,
'errors' => "Data no valid",
];
return $this->response($data, 422);
}

/**
* @param PostRepository $postRepository
* @param $id
* @return JsonResponse
* @Route("/posts/{id}", name="posts_get", methods={"GET"})
*/
public function getPost(PostRepository $postRepository, $id){
$post = $postRepository->find($id);

if (!$post){
$data = [
'status' => 404,
'errors' => "Post not found",
];
return $this->response($data, 404);

PROJECT WEB - WEBG301 6


}
return $this->response($post);
}

/**
* @param Request $request
* @param EntityManagerInterface $entityManager
* @param PostRepository $postRepository
* @param $id
* @return JsonResponse
* @Route("/posts/{id}", name="posts_put", methods={"PUT"})
*/
public function updatePost(Request $request, EntityManagerInterface
$entityManager, PostRepository $postRepository, $id){

try{
$post = $postRepository->find($id);

if (!$post){
$data = [
'status' => 404,
'errors' => "Post not found",
];
return $this->response($data, 404);
}

$request = $this->transformJsonBody($request);

if (!$request || !$request->get('name') || !$request->request-


>get('description')){
throw new \Exception();
}

$post->setName($request->get('name'));
$post->setDescription($request->get('description'));
$entityManager->flush();

$data = [
'status' => 200,
'errors' => "Post updated successfully",
];
return $this->response($data);

}catch (\Exception $e){


$data = [
'status' => 422,
'errors' => "Data no valid",
];
return $this->response($data, 422);
}

/**

PROJECT WEB - WEBG301 7


* @param PostRepository $postRepository
* @param $id
* @return JsonResponse
* @Route("/posts/{id}", name="posts_delete", methods={"DELETE"})
*/
public function deletePost(EntityManagerInterface $entityManager,
PostRepository $postRepository, $id){
$post = $postRepository->find($id);

if (!$post){
$data = [
'status' => 404,
'errors' => "Post not found",
];
return $this->response($data, 404);
}

$entityManager->remove($post);
$entityManager->flush();
$data = [
'status' => 200,
'errors' => "Post deleted successfully",
];
return $this->response($data);
}

/**
* Returns a JSON response
*
* @param array $data
* @param $status
* @param array $headers
* @return JsonResponse
*/
public function response($data, $status = 200, $headers = [])
{
return new JsonResponse($data, $status, $headers);
}

protected function transformJsonBody(\Symfony\Component\HttpFoundation\


Request $request)
{
$data = json_decode($request->getContent(), true);

if ($data === null) {


return $request;
}

$request->request->replace($data);

return $request;
}

PROJECT WEB - WEBG301 8


Here we defined the five routes:
- GET /api/posts: will return a list of the Posts.

 POST /api/posts: will create a new Post.

 GET /api/posts/id: will return a Post matching the specific identifer

PROJECT WEB - WEBG301 9


 PUT /api/posts/id : will update the Post.

This is the result after update:

PROJECT WEB - WEBG301 10


 DELETE /api/posts/id: will delete the Post.

This is the result of get all posts after delete the post with the ID 3:

PROJECT WEB - WEBG301 11


PROJECT WEB - WEBG301 12

You might also like