Building RESTful Web Services with PHP 7

4.3 (4 reviews total)
By Haafiz Waheed-ud-din Ahmad
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. RESTful Web Services, Introduction and Motivation

About this book

REST is the most wide spread and effective standard to develop APIs for internet services. With the way PHP and its eco-system has modernized the way code is written by simplifying various operations, it is useful to develop RESTful APIs with PHP 7 and modern tools.

This book explains in detail how to create your own RESTful API in PHP 7 that can be consumed by other users in your organization.

Starting with a brief introduction to the fundamentals of REST architecture and the new features in PHP 7, you will learn to implement basic RESTful API endpoints using vanilla PHP. The book explains how to identify flaws in security and design and teach you how to tackle them. You will learn about composer, Lumen framework and how to make your RESTful API cleaner, secure and efficient. The book emphasizes on automated tests, teaches about different testing types and give a brief introduction to microservices which is the natural way forward.

After reading this book, you will have a clear understanding of the REST architecture and you can build a web service from scratch.

Publication date:
September 2017
Publisher
Packt
Pages
244
ISBN
9781787127746

 

Chapter 1. RESTful Web Services, Introduction and Motivation

RESTful web services are being used widely nowadays. RESTful is simple and most widely used among other web services. In fact, its simplicity is a reason for its fame as well. If you are reading this book, then chances are that you know something about RESTful web services. You probably have used it or you have just heard of it. But even if you don't know much about RESTful web services, don't worry as we are first defining it right here. So first, let's list the high level topics that we will be covering in this chapter:

  • Web services, what is a web service?
  • REST architecture (constraints of REST)
  • RESTful web services
  • Conventions of RESTful web services

  • HTTP verbs (methods)
  • Why RESTful web services?
  • Response type and response codes
  • Case study - RESTful web service endpoints for a blog

However, there are a lot of misconceptions about RESTful web services. For example, some people think that anything over the web returning JSON is a RESTful web service and RESTful web services only return JSON. This is not true.

In fact, RESTful web services support multiple formats and not everything returning JSON is a RESTful web service. To avoid confusion, let us understand what RESTful web service is.

A web service based on the REST architecture is a RESTful web service. So, what exactly is a web service and REST architecture? Let's start by understanding web service first and then the REST architecture.

 

Web services


Web services are defined differently at different places. Word-by word translation states that any service provided on the web including a web page is a service but this isn't true if the technical term web service is referred to.

To define web service, we will look at web service definition from the W3C glossary:

"A Web service is a software system designed to support inter-operable machine-to-machine interaction over a network. It has an interface described in a machine-process able format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAP-messages, typically conveyed using HTTP with an XML serialization in conjunction with other Web-related standards." -W3C, web services glossary.

This definition again, is not completely true as it is more specific to SOAP and WSDL based web services. In fact, later in the W3C Working Group Note, February 11, 2004, it was stated that:

"We can identify two major classes of web services:- REST-compliant web services, in which the primary purpose of the service is to manipulate XML representations of Web resources using a uniform set of "stateless" operations; - and arbitrary web services, in which the service may expose an arbitrary set of operations."

So considering that, a more general and better definition of a web service is this, from the preceding mentioned W3C web services glossary definition:

"A Web service is a software system designed to support inter-operable machine-to-machine interaction over a network."

Why a web service?

Now, we know what a web service is. So proceeding to REST, it is important to know the need for a web service. Where can a web service be used?

As just defined, a web service is a system to machine-to-machine inter-operable communication over a network. It is very useful for communication between different systems or devices. In our case, we will be using web services to provide an interface by which either a mobile application or a web application will be able to communicate with a server to get and store data. This will make the client-side application separate from the server side logic. And nowadays, SPAs (Single Page Applications) and mobile applications need to be stand alone, separate from server side and only interacting with server side logic with web services. So definitely web services are very much important nowadays. However, web service usage is not limited to client side application usage but it is also useful in server to server communication where one server acts as a client.

 

REST architecture


REST stands for Representational State Transfer. It is an architectural style founded by Roy Fielding in 2000 and was stated in his PhD dissertation. He stated that REST

"provides a set of architectural constraints that, when applied as a whole, emphasizes scalability of component interactions, generality of interfaces, independent deployment of components, and intermediary components to reduce interaction latency, enforce security, and encapsulate legacy systems."

.

REST is an architectural style a network-based application and HTTP 1.1 was based on it, as it was developed in parallel to HTTP 1.1.

A RESTful system or RESTful web service must abide by the following six constraints; otherwise, it will not be considered as RESTful or REST-compliant. While reading and understanding the following mentioned constraints, think about the modern web as an example of REST architecture.

Client server

REST is about separating the client and server. This constraint is about "separation of concerns". It means that the server and client have separate responsibilities, so one is not responsible for the other's duties. For example, the client is not responsible for data storage on the server as it is the server's responsibility. In the same way, the server doesn't need to know the user interface. So both the server and perform their tasks and fulfill their own responsibilities which makes their work easier. Hence, the server can be more scalable and the user interface on the client can be independent and more interactive.

Stateless

Client server communication is stateless. Each request coming from the client will have all the information required to serve a request. This means there is no state in communication other than what is in the request. The response which the client will get will be based on the request without looking at any state other than what is in request.

If the session needs to be maintained, the session will be stored based on a token or identifier which is coming in the request. So if we look at an example of a web request, then the flow of HTTP is no more than a request sent by the client to the server and a response, sent back to the client from the server, as shown in the following diagram:

If a session needs to be maintained, the session data will be stored on the server, while the session identifier will be sent back to the client. In subsequent requests, the client will include that session identifier in every request by which the server will identify the client and load the related session's data as explained in the following diagram:

And in subsequent requests:

So REST is stateless. To maintain the state, one needs to pass an identifier or any other information, to logically group different requests to maintain a session in the request. If no such identifier is passed in the request, the server will never know if those two requests are from same client.

The advantage of statelessness is simplicity. The same requests will not result in different responses unless the request parameters are changed. It will return different based on different request parameters not due to some sort of state. Even the state depends on requests, as shown in the preceding example. So that session identifier is in the request, which can result in a different state and, hence, results in a different response.

Cache-able

This constraint specifies that a RESTful web response must define itself as cache-able or not, so that the client can know whether it should be cached or not. If it is correctly defined, it can result in less overhead and better performance because the client will not go to the server if it is able to use the cached version.

Uniform interface

The uniform interface is the most distinguishing constraint. It basically the architecture makes the interface separate from the implementation, just as any system does.

It is similar to how it is in OOP: an interface separates the implementation and declaration. It is similar to how an operating system separates the user interface from the complex implementation logic that keeps our software's running.

The uniform interface has four constraints. In order to understand uniform interface, we need to understand these constraints.

Resource identification

Resources will be identified in requests. For example, a resource in a web-based REST system will be identified by the URI. And no matter how a resource is on the server, it will remain separate from what will be returned to the client in the response.

In fact, resource storage on the server is an implementation but the request and response is what a client is interacting with, so it is like an interface to the client. And a client can identify a resource by this interface. So all that a client knows is what it is requesting and getting in response.

For example, a client usually sends a request to the URI and gets a response in the form of HTML, JSON, or XML. None of these formats are how the server data internally in the database or somewhere else on the server. But for a client, it is the URI where it will hit and the HTML, JSON, and XML is what it gets.

This is what a resource is for a client, no matter how it is stored on the server. And this is the benefit, because no matter if the server's internal logic or representation is changed, for the client it will remain the same because the client sends the request to the URI and gets a response in the form of HTML, JSON, or XML and not how it is stored on the server. This constraint, results in loose coupling of resource identification and representation.

Manipulation of resources through representations

This constraint states that the client should hold representation of a resource that has enough information to modify or delete the resource. For example, in the web-based REST system, any operation can be performed on a resource using the HTTP method and URI. This makes things easy to follow, as the API developer doesn't need to provide documentation for each and every endpoint related to a resource.

Self-descriptive messages

This constraint states that each message should be to be processed based on information contained in itself. That means, every message passed between the server and client should be stateless be independent of other messages. One message doesn't have an impact on other messages. So, it doesn't matter if two messages are passed in some particular order or not, as they are independent. The request in a message is enough to get a response and that response has all that needs to be conveyed.

Hypermedia as the engine of application state (HATEOAS)

This constraint states that, based on what a server provides to a REST client, the REST client should be able to discover all available actions and resources. In other words, it states that if a knows an entry point then from that first endpoint, it should be able to discover relevant endpoints related to that resource. For example, if a client goes to a resource's listing endpoint, that should include links to resources in that listing. And if there is pagination or limit being applied, it should have links to go to the rest of the items in the listing.

If a client has created a new resource, the new resource's link should be included in response as well which can be used for read, update, and delete operations on that resource by using different HTTP verbs. For operations other than typical CRUD, it will obviously have more URLs, so URLs for those operations should also be in the response, so that all endpoints related to the resource can be discoverable from one entry point.

Due to HATEOAS, an endpoint exposes links to related endpoints. This reduces the need of a thorough API documentation, although not completely, but one does not need to see the API documentation for the links already being exposed.

Code on demand (optional)

This states that the server can add more functionality the REST client, by sending code that can be executable by that client. In the context of the web, one such example is JavaScript code that the sends to the browser.

Let's consider an example to understand this better.

For example, a web browser acts like a REST client and the server passes HTML content that the browser renders. At the server side, there is some sort of server-side language which is performing some logical work at the server side. But if we want to add some logic which will work in the browser then we (as server-side developers) will have to send some JavaScript code to the client side and the browser and then execute that JavaScript code. So that the JavaScript code can add validation to a form, some animation or anything else, that couldn't be possible simply in HTML content. That JavaScript code is code on demand which the server sends to the client that extends the functionality of the REST client.

Note that sending code on demand to the client is optional, and not required if we don't want to extend the client's functionality.

Layered system

This constraint states that the REST system can multiple layers and if a is requesting for a response and getting a response, it can't be differentiated if it was returned from the server or another middle-ware server. So if one server layer is replaced by an other, it doesn't affect the client unless it provides what it is expected to provide. In short, one layer doesn't have knowledge beyond the next layer with which it is interacting directly.

 

RESTful web services


As we have already defined REST and web services, we can say that a RESTful web service is any web service that is REST-compliant.

Now, as we have already defined RESTful web services, we need to learn how RESTful web services work, and what RESTful web services are based on and why they are preferred over other web services such as SOAP.

Conventions of RESTful web services

RESTful web services are on RESTful resources. A RESTful resource is an entity/resource that is mostly stored on a server and that client request using RESTful web services. Here are a few characteristics of a resource in terms of RESTful web services:

  • It is an entity normally referred as a noun in the URL
  • It is unique
  • It has data associated with it
  • It has at least one URI

If you are still wondering what exactly is a resource, consider the example of a blog. In a blog system, a Post, User, Category, or Comment can be a resource. In a shopping cart, a Product, Category, or an Order can be a resource. In fact, any entity which a client is requesting from the server is a resource.

Most commonly, there are five typical operations which can be performed on a resource:

  • List
  • Create
  • Read
  • Update
  • Delete

For each operation, we need two things: the URI and HTTP method or verb.

The URI contains a resource name that is a noun and the HTTP method that is a verb. To perform some operation on an entity, we need to have a noun that tells us which entity we need to perform some operation. We also need to specify a verb to tell us what operation we want to perform.

For the preceding mentioned operations, there is a URL convention that we use with HTTP verbs and resource names. In the next section, we will review the URL structure and HTTP verbs for each operation.

HTTP verbs and URL structure

Here is how these operations be performed a resource a combination of URIs and HTTP verbs. Note, in the following mentioned operation's URIs, you to replace {resource} with a resource name.

List operation

  • HTTP method :GET
  • URI:/{resource}
  • Result: It returns the list of the type of resource name is mentioned. In that list, it will give unique identifiers for the resource and these identifiers can be used to other operations on that particular resource.

Create operation

  • HTTP method :POST
  • URI:/{resource}
  • Parameters: can be multiple parameters in POST body
  • Result: This should create a new with parameters in the body.
  • As you can see, there is no difference in the URI for Create and List but two operations are distinguished by the HTTP method which results in different operations. In fact, a combination of the HTTP method and URI tells which operation should be performed.

READ operation

HTTP method: GET

URI: /{resource}/{resource_id}

Result: This should return the based on the resource's ID.

Here resource_id will be the ID of the resource which can be from the List operation's result.

Update operation

There can be two of update operations:

  • Update some attributes of a record
  • Replace that particular record completely with a new one

Only thing that change to perform these two operations: HTTP method.

With the Update operation, to update some of attributes of the resource use:

HTTP method: PATCH

While to replace the whole resource use:

HTTP method: PUT

The URI and the parameters will remain the same:

URI: /{resource}/{resource_id}

Parameters: There can be multiple parameters in a query string. Initially, people try to pass these parameters in the body but actually, the PATCH and PUT parameters are passed using a query string.

Result: This should update or replace the resource based on the HTTP method.

Here, resource_id will be the ID of the resource which can be found from the List operation's result. Again, practically using PATCH or PUT will not make any difference but based on REST standards PATCH should be used for updating the different attributes of a record while PUT should be used for replacing the whole resource.

Delete operation

  • HTTP method: DELETE
  • URI: /{resource}/{resource_id}
  • Result: This should delete the resource based on the resource ID in the URI

If you feel overwhelmed at the moment, don't worry, because right we have just seen combination of HTTP method and URI is used for which operations. Shortly, we will discuss a case study and will see some operations on different resources along with examples.

Before anything else, since we now know about RESTful web services and how they work, it's a good time to understand why we prefer to use RESTful web services over other web services.

 

Why RESTful web services?


In fact, RESTful web services are not the only of web services that we can write. There are other ways to write web services as well. There are old ways of writing web services as well as some more recent ways. We will not go in to detail about other web services, as that is out of the scope of the book, with the focus here being on RESTful web services and how to build them.

REST versus SOAP

One old alternative to REST is SOAP. In fact, SOAP was already, used REST came along as an alternative. A key difference is that SOAP doesn't have some particular convention that tells consumers how to access that. SOAP exposes its services using WSDL. Consider WSDL as a definition of that SOAP provides. This is how the consumer knows what SOAP based web service provides and how to consume them.

On the other hand, REST emphasizes on "c

onventions over configurations

". If you look at the URL structures and HTTP verbs of RESTful web services as we did earlier, there is a fixed convention. For example, if you are at the client side and want to create a product, if you know what parameters it will take then you can simply create it by sending a POST request to example.com/product and the resource will be created. If you want to list all the products, you can use the same URL with a GET request. If you get product IDs from the List operation, you can simply use them to update or delete a product by using example.com/product/{product_id} using PATCH and PUT or DELETE respectively. It is that simple to know what URL and HTTP method to use to do a type of operation because these are some conventions that RESTful web services follow. So, the one on the client end will just follow those conventions and will not need large documentations for simple tasks.

Other than that, simplicity of statelessness, separation of concerns, and cache-ability are some of the other advantages of RESTful web services that we have already seen in detail.

 

Nature of HTTP methods


Since we will be dealing with URLs over HTTP and will be using HTTP methods, it is better to spend some time understanding the nature of HTTP methods.

We should also understand that HTTP methods are not actually doing any type of listing or creation or modification by themselves. It is just a convention to use certain HTTP methods and URL patterns for certain operations. These methods do not perform any operations on their own but it depends on the server-side developer. These methods can result in any operation depending on the code that the developer writes.

When we talk about the nature of HTTP methods, then it is about the convention and standards which are followed. After all, RESTful web services are about preferring convention over configuration. The foundation of today's HTTP and REST lies on these conventions and while writing RESTful web services, we are going to follow these conventions.

Safe/unsafe HTTP methods

HTTP methods can be both safe or unsafe. By safe, it means the methods not expected to any resource on the server and by unsafe it means the are expected to change resource on the server. So this way, we have GET as the only safe method, as it is not expected to change anything on the server while other methods such as PUT, POST, PATCH, and DELETE are considered as unsafe methods since they are expected to do some changes on the server.

Idempotent and non-idempotent methods

There are methods which achieve the same results matter how many time repeat the same operations. We consider GET, PUT, PATCH, and DELETE as idempotent methods, as no matter how many times we repeat these method calls, it will always result in the same thing. For example, if you are using GET example.com/books , it will always return the same list of books, no matter how many times you call this URL with the GET method. However, if user put something else in database then it can have different result in listing but to declare some method idempotent or not, we are not considering change in result because of external factors instead of that method call itself. In the same way, if you use PUT or PATCH, let's say PATCHexample.com/books/2?author=Ali, it will always result in the same response no matter how many times you call this method with the same parameters.

The same is the case with DELETE. It doesn't matter many times you call DELETE on the resource, it will only be deleted once. However, for DELETE, it can vary based on the implementation as well. It is something that depends on how you as a programmer want to implement. You probably want to DELETE and give a successful response the first time and on subsequent calls. You can simply give 404 because the resource no longer exists.

POST is non-idempotent because it creates a new resource on the server and the response has at least one unique attribute (mostly that is the ID of the resource), even if all the other attributes are same in the case of the same request parameters.

Until now, we have understood RESTful web services conventions, URL patterns, HTTP methods, and the nature of HTTP methods. However, it was mostly about requests. The URL and HTTP method are both request-related points. We haven't yet looked at responses, so now let's take a look into that.

 

HTTP response


The purpose of the request is to get a response or it is of no use, considering that we also need to understand what type of response is expected against a request. There are two things that we will discuss in this context:

  • Response type
  • Response code

Response type

In the current world, many people think that the of a RESTful web service be a JSON or text having a JSON string. However, we can also use XML in response to a RESTful web service request. A lot of people use JSON in response because it is lightweight and easy to parse. But at the same time, this is just a matter of preference, and depends on the requirement and has nothing to do with REST standards.

Both XML and JSON are ways to format data. XML stands for Extensible Markup Language, having markup syntax. While stands for JavaScript Object Notation, with JavaScript object-like syntax. For more understanding of JSON, please check out http://www.json.org/

We will shortly look into the case study of a blog and will see request and response examples. In this book, will use JSON as the response type, as JSON is simpler than XML. And while developing new applications, we mostly use JSON because it is lightweight and easy to understand. As you can see in the following examples, the same data in JSON is much simpler than XML and only has content that matters.

Here, we are trying to show the data of books having one or more authors:

XML:

<books>
  <book>
    <name>Learning Neo4J</name>
    <authors>
      <author>Rik Van Bruggen</author>
    </authors>
  </book>
  <book>
    <name>
     Kali Linux – Assuring Security by Penetration Testing
    </name>
    <authors> 
      <author>Lee Allen</author>
      <author>Tedi Heriyanto</author>
      <author>Shakeel Ali</author>
    </authors>
 </book>
</books>

Now, let's look at the same example in JSON:

{
books: [
  {
    name:"Learning Neo4J",
    authors:["Rik Van Bruggen"]
  },
  {
    name:"Kali Linux – Assuring Security by Penetration Testing",
    authors:["Lee Allen", "Tedi Heriyanto", "Shakeel Ali"]
  }
 ]
}

You can clearly see from the preceding example, that XML and JSON both convey the same information. However, in JSON it is much easier as well as it needs a lot less words to show the same information.

Hence in the rest of book, we will be using JSON as the response type of our RESTful web services.

Response codes

Response codes, better known as HTTP status codes, tell us about the status of a request. If an HTTP request is successful, the HTTP status code is 200 which means OK. If there is a server error, it returns 500 status code which means an internal server error. In case of any problem in the request, the HTTP status code is 400 and onwards where 400 status code means a bad request. In case of redirection, the response code is 300 and onwards.

To see complete of response and their usage, see https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

I won't go into details of it as it would be redundant since all of it is already available at the preceding mentioned Wikipedia link. However, we will discuss the different status codes as we proceed.

 

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 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.

Note

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.

Note

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 a blog post 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 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 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 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 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 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 untouched.

Delete blog post
  • Request: DELETE /posts/1 HTTP/1.1
  • Response:
{success:"True", deleted_id:1 }
  • Response code: 200 OK

Note

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 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 post comment and its endpoints. For those endpoints, we will write Request and Response.

Requirements

There will be one, more than one, or 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 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 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 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 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 exist, it should return 404Not 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 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.

 

More resources


Although we have tried to look into web services in a way that one gets practical knowledge with the examples, here are some other interesting resources.

Dissertation of Roy Fielding in which he introduced REST:

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

A group discussion with Roy Fielding's response:

https://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/6735

This is an interesting thread at stackoverflow.com regarding REST versus SOAP:

http://stackoverflow.com/questions/19884295/soap-vs-rest-differences

Roy Fielding talking about REST :

https://www.youtube.com/watch?v=w5j2KwzzB-0

A different way to look at REST:

https://www.youtube.com/watch?v=RY_kMXEJZfk

 

 

Summary


In this chapter, we understood what a RESTful web service is. We looked at constraints that should be fulfilled to be called as a RESTful web service. Then we understood that REST is an architecture and it is a way to build stuff and it favors convention over configuration. We looked at HTTP verbs (methods) and looked at URL conventions. We understood that these are just conventions. HTTP verbs and URLs are used in RESTful web services; otherwise it is always up to the developer to provide the expected behavior as REST has conventions which are just considered as standard but it don't provide any implementation.

In this chapter, we didn't talk about the implementation of RESTful web services. We just considered a case study of a typical blog and took examples of two resources of the blog and defined their endpoints with the expected responses. We also looked at HTTP response code but we didn't write actual code to implement these RESTful web services. We defined these endpoints, so we will see their implementation in the next chapters.

As this book is about building RESTful web services in the PHP7, in next chapter we will look at the features that came in PHP7. PHP7 does not offer anything specific to RESTful web services but we will be utilizing some of the new features in PHP7 to write better and clean code to build RESTful web services.

If you already know PHP7 well and don't wish to dig into that at the moment, you can skip Chapter 2, PHP7, To Code It Better, and start Chapter 3, Creating RESTful Endpoints, where we will build RESTful web services.

About the Author

  • Haafiz Waheed-ud-din Ahmad

    Haafiz Waheed-ud-din Ahmad has been working in the IT industry since 2008. He has mostly worked in web application development and mostly used PHP at the server side. Although most of his experience is in PHP, he is a technology agnostic person and also likes to learn and adapt to new technologies. He also acts as an adviser for startups and new developers.

    He has worked on Python and JavaScript as well. He likes to experiment with new technologies, and he has also explored Golang, Scala, and Neo4J. He also has a keen interest in data science and big data domain and has worked on D3.js for data visualization. He is not just a technology enthusiast but also likes to solve day-to-day problems by the usage of technology. You can follow him on twitter at @Haafiz786.

    Browse publications by this author

Latest Reviews

(4 reviews total)
Good content. Because of e-book, readers can access more books at cheaper cost.
OK but the checkout process was not appealing to me. I have to break my single transaction down into three to realize the discount offerred. This, to me, is a deficiency of the system.
Great service experience and great price

Recommended For You

Building RESTful Web Services with PHP 7
Unlock this book and the full library for FREE
Start free trial