Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Building RESTful Web Services with PHP 7

You're reading from   Building RESTful Web Services with PHP 7 Lumen, Composer, API testing, Microservices, and more

Arrow left icon
Product type Paperback
Published in Sep 2017
Publisher Packt
ISBN-13 9781787127746
Length 244 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Waheed ud din Waheed ud din
Author Profile Icon Waheed ud din
Waheed ud din
Arrow right icon
View More author details
Toc

Table of Contents (10) Chapters Close

Preface 1. RESTful Web Services, Introduction and Motivation FREE CHAPTER 2. PHP7, To Code It Better 3. Creating RESTful Endpoints 4. Reviewing Design Flaws and Security Threats 5. Load and Resolve with Composer, an Evolutionary 6. Illuminating RESTful Web Services with Lumen 7. Improving RESTful Web Services 8. API Testing – Guards on the Gates 9. Microservices

Case study - RESTful web service endpoints for a blog

To understand RESTful web services, let's consider the case study of a blog where we will discuss resources/entities in a blog. We will start to define the requirements and endpoints URLs for the blog's resources and then define responses that we should have against those requests. So these endpoints and response definitions will help us understand how RESTful web services endpoint should look like and what the response should be. In the later chapters, we will talk more about the implementation of these endpoints, so these definitions will act as an API document for the next chapters. However, for simplicity, we will keep it minimal for now and later add more attributes to it.

Although based on HATEOAS, a RESTful web service should return links to the next endpoints and there are conventions that tell us about other endpoints but the API document is still important. API consumers (client-side developers) and API providers (server-side developers) should agree on it so that both can work in parallel without waiting for the other. However, in the real world, we don't have to write API document for basic CRUD operations.

In a typical blog, the most common resources are posts and comments. There are others as well but for now, we will discuss these two resources for the sake of understanding RESTful web services. Note that we are not considering authentication related stuff but will look into that in the later chapters.

If client-side and server-side teams are of the same organization, working on a single app, then it is a good idea to get such document created by the client-side team as the server-side team is just the serving client side.

Blog post

Here, we are listing the requirement of a blog post and its endpoints. For those endpoints, we will write a request and a response.

Requirements

A blog post can be created, modified, visited, and deleted. There should also be a way to list all the blog posts. So we are going to list the blog post's endpoints.

Endpoints

Here are the endpoints for blog post:

Creating blog post

  • Request: POST /posts HTTP/1.1
  • Body parameters:

Content: This is an awesome post
Title: Awesome Post

  • Response:
{id:1, title:"Awesome Post", content:"This is an awesome post", link: "/posts/1" }
  • Response code: 201 Created

Here POST is the method, /posts is the URL (path after the server name) and HTTP 1.1 is the protocol. We will keep using the same way of mentioning requests in later examples as well. So, the first part of the request is the HTTP method, the second one is the URL and the third part is the protocol.

The response code tells the client that the resource has been created successfully. If a request parameter is missed by mistake, the response code should be 400, which represents a bad request.

Reading blog post

  • Request: GET /posts/1 HTTP/1.1
  • Response:
{id:1, title:"Awesome Post", content:"This is an awesome post", link: "/posts/1" }
  • Response code: 200 OK

Note, if a blog post with an ID provided (in the current case, 1) does not exist, it should return 404, which means resource Not Found.

Updating blog post

  • Request: PATCH /posts/1?title=Modified%20Post HTTP/1.1
  • Response:
{id:1, title:"Modified Post", content:"This is an awesome post", link:"posts/1" }
  • Response code: 200 OK

Note, if a blog post with the ID provided (that is 1 in this case) does not exist, it should return the response code 404 that means resource not found.

Also, we have used PATCH instead of PUT for the update since PATCH is used to modify all or some attributes of a record while PUT is used for modifying a whole record just like replacing an old record with a new one. So, if we use PUT and pass only one attribute, the other attributes will become empty. In the case of PATCH, it will only update the attribute that is passed and other attributes remain untouched.

Delete blog post

  • Request: DELETE /posts/1 HTTP/1.1
  • Response:
{success:"True", deleted_id:1 }
  • Response code: 200 OK
Note, if a blog post with an ID provided (in the current case, 1) does not exist, it should return 404, which means resource Not Found.

Listing all blog posts

  • Request: GET /posts HTTP/1.1
  • Response:
{
data:[
{
id:1, title:"Awesome Post", content:"This is an awesome post", link: "/posts/1"
},
{
id:2, title:"Amazing one", content:"This is an amazing post", link: "/posts/2"
}
],
total_count: 2,
limit:10,
pagination: {
first_page: "/posts?page=1",
last_page: "/posts?page=1",
page=1
}
}
  • Response code: 200 OK

Here, data is an array of objects as there are multiple records returning. Other than total_count, there is a pagination object as well, and right now it shows the first and last pages because total_count for records is only 2. So, there is no next or previous page. Otherwise, we should also have to show the next and previous in pagination.

As you can see, there are links in the pagination as well as the post's links in post objects. We have included these links in response to being compliant with the HATEOAS constraint, which stated that if the client knows about an entry point, it should be enough to discover relevant endpoints.

Here, we explored the requirements of blog posts and defined the request and response of their endpoints. In the next entity/resource, we are going to define endpoints and responses in comments.

Blog post comments

Here, we are listing the requirements of a blog post comment and then its endpoints. For those endpoints, we will write Request and Response.

Requirements

There will be one, more than one, or no comments on posts. So, a comment can be created on a blog post. A blog post's comments can be listed. A comment can be read, modified, or deleted.

Let's define endpoints for these requirements.

Endpoints

Here are the endpoints for the post's comments:

Creating the post's comment

  • Request: POST /posts/1/comments HTTP/1.1
  • Body parameters: comment: An Awesome Post
  • Response:
{id:1, post_id:1, comment:"An Awesome Post", link: "/comments/1"}
  • Response code: 201 Created

Here in the case of a comment, a comment is created against a certain blog post. So, the request URL includes post_id as well.

Reading a comment

  • Request: GET /posts/1/comment/1 HTTP/1.1 or GET /comment/1 HTTP/1.1

The second one seems more reasonable as in that one only needs to have a comment's ID without worrying about the post ID of that comment. And since a comment's ID is unique, we don't need to have the post's ID to get the comment. So, we will proceed with the second URL that is GET /comment/1 HTTP/1.1.

  • Response:
{id:1, post_id:1, comment:"An Awesome Post", link: "/comments/1"}
  • Response code: 200 OK

Since any comment can only exist against some post, the response includes post_id as well.

Updating a comment

  • Request: PATCH /comment/1?comment="Modified%20Awesome%20Comment' HTTP/1.1
  • Response:
{id:1, post_id:1, comment:"Modified Awesome Comment", link: "/comments/1"}
  • Response code: 200 OK

Here, we used PATCH as we want to update a single attribute of a comment that is a comment. Also, you can see %20 passed in a new comment. So, %20 is just a replacement for a space as a URL cannot contain spaces. So with URL encoding, spaces should always be replaced by %20.

Deleting a post comment

  • Request: DELETE /comments/1 HTTP/1.1
  • Response:
{success:"True", deleted_id:1 }
  • Response code: 200 OK

Note, if a post comment with an ID provided (in the current case, 1) does not exist, it should return 404 Not Found.

Listing all comments for a particular post

  • Request: GET /posts/1/comments HTTP/1.1
  • Response:
{
data:[
{
id:1, comment:"Awesome Post", post_id:1, link: "/comments/1"
}, {
id:2, comment:"Another post comment", post_id:1, link: "/comments/2"
}
],
total_count: 2,
limit: 10,
pagination: {
first_page: "/posts/1/comments?page=1",
last_page: "/posts/1/comments?page=1",
page=1
}
}
  • Response Code: 200 OK

As you can see, a post's comments listing is very similar to a blog post's listing. And it has total_count and pagination in the same way. It shows the first and last page right now because total_count for the records is only 2. So there is no next or previous page. Otherwise, we should also have to show the next and previous links in pagination.

Normally, you don't see pagination with comments on blogs, but it is better to keep it consistent to have pagination in the listing. Because there can be lot of comments for a post, we should apply some limit to it, so we will need pagination.

You have been reading a chapter from
Building RESTful Web Services with PHP 7
Published in: Sep 2017
Publisher: Packt
ISBN-13: 9781787127746
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image