PHP REST API with nested routes - php

I want to create a pure PHP REST API and I am quite new in backend development field, but I am experienced software developer, so some concepts are known to me.
However, after watching several tutorials on how to create REST API with PHP, all instructors were using simpler examples, where no nesting exists.
Simple Example:
GET /api/category/read.php
However, I want to create something like this:
GET /api/{user_id}/{folder_id}/{file_name}/read.php
I am struggling to find any tutorial covering this with PHP. And I have spent several hours trying to figure it out by myself by trying to modify the code I have seen in Tutorial videos. I mean if I do like they do, this would mean manually creating folders in my Project Folder for each {user_id} and so forth for each sub-folder... but I do not think that such hardcoding is the solution.
I have found some SO questions here relating closely to my question, but none have satisfying answers - makes me wonder that this if this is possible to do at all. But it seems so common (for example, I know that GitHub API has just that support /{user}/repos) so I think it should be doable.
I would be really grateful if someone could help me out how to accomplish my goal. If not else, pointing to a tutorial / documentation that does just that is equivalently appreciated!

You do not need to create the folder structure to achieve this. It would be more advantageous to use something like Apache Mod Rewrite or a framework like Laravel to help avoid the need to create the file structure you are describing and have a single endpoint for handling specific routes:
Using mod rewrite with Apache2 would work something like:
.htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^api/(.+)/(.+)/(.+)/read /api/read.php?user_id=$1&folder_id=$2&file_name=$3
This would provide the URI variables in the $_GET and $_REQUEST supergobals in /api/read.php
Using the Laravel framework you can leverage their MVC approach and create dynamic routes which can capture the URL vars and deliver them to the desired Controller endpoint:
in your routes file:
Route::get('api/{user_id}/{folder_id}/{file_name}/read', Controller#read)
in the Controller:
public function read(user_id,folder_id,file_name){ /* do stuff */ }
There is alot more to know about the specifics of MVC and using Laravel to create an API, however, they have great documentation and tutorials.

Create a PHP script that receives every request (have Apache direct all requests to it), and then process the $_SERVER['REQUEST_URI'] variable to split the path into segments, storing the parts in variables of your choice. Then dispatch the request to sub-components as necessary.

Related

How to create a RESTful API in php

I'm looking to generate a RESTful API in PHP and based on my experience using them in the past my instinct is to make a PHP script for each function (since they appear at different URLs). However, I then thought that that would be odd because of the levels of hierarchy present in most REST functions I've seen and the fact that none of the REST URLs I've ever seen have any kind of suffix (ie .php). Can someone explain to me the ideal way to setup a RESTful API using PHP so that works the way you might expect a RESTful API to work?
Generally if you see domain.com/users/validate that is a clean way of accessing an API using something such as mod_rewrite (.htaccess) for my clients I generally stick with domain.com/?method=SOMETHING,etc.

Is it bad practice to request index.php in order to use other scripts

Is it bad to use index.php as loader for other scripts or does it make a difference?
i.e. requesting index.php with different query strings and inside it, selecting and including the matching script.
e.g.
www.example.com/?sign-in insteade of www.example.com/sign-in.php
www.example.com/?new-post insteade of www.example.com/new-post.php
In this way you can use index.php to do the common inclusions and processes, like, setting timezone, mb encoding, DB connection, auth, etc..
Best practice is to let apache rewrite all urls to an index.php or some other file which you can use as bootstrap. This bootstrap runs all the basic code and then this bootstrap can figure out which other actions to take based on the url.
Every framework works like this.
several things you might want to do in the bootstrap:
setup, autoloading classes
setup mysql connection
check if user is authenticated for a certain action
There are many tutorials on rewriting urls with apache: http://www.workingwith.me.uk/articles/scripting/mod_rewrite
If you really want to learn about best practices i would suggest looking at existing frameworks, at how they implement certain things. eg: Zend or Symfony
Yes and No
The problem is that by doing it you will lose any SEO value, eg: domain.com/index.php?post=story will rank very poorly against domain.com/post/story . Also your index.php is going to get messy very quickly.
That being said MVC's usually use a index.php, so my url would be domain.com/users/edit/123 which is a very logical url, but what actually gets called is domain.com/index.php , it then looks at the first paramater, "users" and instantiates the user controller and then looks for the function edit inside that and passes the "123" (user id) as the first parameter in the function. If you are not familiar with MVC's I would advise codeigniter as a starting one, more on codeigniter.
In the end you will just be re-inventing the wheel by building it from scratch, rather use a MVC make development much easier.
This is the best approach. You can take control of your website.
Create index.php and include other files on demand.
(Define a constant and use it in included files and so on)
But keep in mind to minimize index.php as much as possible.
Also you can use Apache mod_rewrite to generate SEO friendly URL.
Instead of routing all your requests (through htaccess) to index.php you can also split the routes to map to other files:
/blog/hello-there mapping to blog.php?title=hello-there
/sign/in mapping to login.php?login
etc, thus you create your own simple routing based on the request URL; easy to read and easy to maintain.
This solution is suitable in small projects, for bigger project I advise to use a complete framework like Yii or Symfony.

Routing REST requests without framework?

I have been reading the article to learn how to build a rest API:
http://www.gen-x-design.com/archives/create-a-rest-api-with-php/
At one point it says "Assuming you’ve routed your request to the correct controller for users"
How can I do this without a framework?
I am writing a REST API that I can interact with from a different application. I ready the tutorial above, and it makes sense mostly, but I don't exactly understand what it means to route my request to the correct controller for users.
Assuming you are using Apache, you can accomplish this easily using a combination of mod_rewrite and some PHP-based logic. For example, in your .htaccess or vhost definition, you could route all requests through a single handler, possibly index.php:
# Don't rewrite requests for e.g. assets
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*+)$ index.php?q=$1 [L]
...then in your index.php file do something like:
$target = $_REQUEST['q'];
/* parse the request and include the appropriate controller PHP */
For example, a request for /products/1234 might result in a controllers/products.php handler being included. That handler could then act on product 1234. Because you're using REST, you shouldn't need to be concerned with the original request having a query string parameter.
There are multiple ways to accomplish what it sounds like you're trying to do, this is just one of them. Ultimately what you go with will depend on what your specific requirements dictate. The above pattern is fairly common however, many frameworks use it or something like it.
I think this is a matter of terminology. Every code with some level of generalization can be called "framework". And since you're asking about "routing", which provides a starting level of generalization, every implementation becomes a framework.
If you don't want to use existing fully-fledged frameworks, you can elaborate your own light-weight-implementation. Here is some articles to start:
Write your own PHP MVC framework
PHP MVC framework in one hour
(the author has decided to remove this post because he thinks that using a modern fully-fledged framework is more appropriate way of programming such things, yet some people find such simple and stripped-down approache more suitable in many aspects: learning, efficiency, no huge dependencies, etc); the post is available on some other sites, for example, in the wayback machine or copies
The Model View Controller in PHP
All these intros include explanations of the routing mechanizm and demonstrate its implementation.
Basically, a router is a kind of internal "DNS" (in a figurative sense) inside your application. When a request arrives to your site, you need to dispatch it to appropriate worker class, according to that request properties. This is the router's task.

Zend Framework – subdirectories and deprecating action within the URL

I’m in the process of learning to use the Zend Framework, and I’m therefore trying to grasp the concept of MVC. Through the Zend manual, and a very helpful Youtube video tutorial I have sort of understood the concept – still there are some things I need to clarify.
The web project I’m currently working on is a web site for an organization I’m a part of. It consists of:
The public portion, mainly consisting of information about us, a calendar and some media – mostly static information, but a couple of pages, like the calendar, will need to retrieve some data from the DB.
The internal pages, which after a login will allow users to RSVP to events and comment them as well.
The administrative controls , allows the admins to add events and manage users etc.
So far it looks like Zend wants the URL to look like this:
http?://[domain]/[controller]/[action]
So here are my questions:
Do I always have to have an action in the url, or will the lack of an action use the index-action as default?
Can I have a subdirectory to distinguish between the internal and public portions of the site: http://[domain]/internal/[controller]/[action] ?
Can this be done simply by having a subfolder within the different MVC-folders somehow?
The latter question isn’t really that important, but I’d like to separate the two portions of the site somehow.
Do I always have to have an action in the url, or will the lack of an action use the index-action as default?
A controller can have a default action which is triggered when no action is specified in the URL. Look for default action or index action.
Can I have a subdirectory to distinguish between the internal and public portions of the site: http://[domain]/internal/[controller]/[action] ?
Yes you can have, but I assume subdirectory refers to your URL, not to the actual file-layout on the server. You can do so by just having a controller per "subdirectory".
Can this be done simply by having a subfolder within the different MVC-folders somehow? The latter question isn’t really that important, but I’d like to separate the two portions of the site somehow.
You can separate per controller and you can even separate with modules. As far as I know of modules in zend-framework, this will all be in it's own sudirectory per module.
I think you're especially looking for Using a Conventional Modular Directory Structure.
The questions you are asking are in the area of routing which generally means: Given a URL on which the HTTP request is being made:
Which controller should be instantiated?
Which action on that controller should be run?
What parameters should be passed to the action?
The routing docs in the ZF Manual explain how routing works by default and how you can specify your own routing. But looking at them now, I don't think they do a great job of introducing the subject matter for a first time user. This post might be better, though it is only a single, simple example.

Create a REST API From a PHP API

I am a beginner with PHP but I know most of the basics. I currently have an API for my website, coded myself, of which I can call different methods with different parameters and they will scour my databases for the relevant information.
However I want to convert it to REST.
So instead of having requests like this http://mywebsite.com/api/?param=allPosts I would have something like http://mywebsite.com/api/posts/. I would do this for each of my 23 different params.
How could I do this?
One way would be to use a micro framework for routing. This would 'point' url request patterns to relevant php files (controllers) to manage those requests and serve content (or perform CRUD operations, or whatever it is your API does).
There's a good post here with some discussion and further links.
https://stackoverflow.com/questions/115629/simplest-php-routing-framework
I'm currently in the process of using the framework Silex for this exact purpose
http://silex-project.org/
It may be that you wish to convert your PHP application to use one of the many frameworks out there (which will handle routing amongst other things).
The usual suspects are
CakePHP
Codeigniter
Symfony
Lithium
and there are many more...
This is not strictly speaking RESTful that is just prettifying your URL's.
To "Prettify" your URL's you could implement something like this:
Trim your base URL of the start of the request
explode the remaining string by the "/" component
The first component (normally) is related to your controller
The next component is your action in this case equivalent to how your using ?param=allPosts
RESTful routing is based around the idea of using the different HTTP verbs (GET/POST/PUT/DELETE) to decide what actions to take on your resources on the server. Wikipedia has a good overview.
One way would be to use apache's mod_rewrite to effectively convert the second type of request to the first. It's not necessarily ideal, but it's a pretty straightforward solution to your problem.

Categories