I really want to make a rest api project but i can't understand how.
For now i have all the html css and php pages, i have a functional php app with database.
Also i have slim routes tested with Postman and all works(return Json). My question is: how do i link all that parts to make a functional rest api aplication?
My routes looks like that:
$app->get('/api/users', function( Request $request, Response $response){
$sql = "SELECT * FROM users";
try {
$db = new db();
$db = $db->connect();
$stmt = $db->query( $sql );
$users = $stmt->fetchAll( PDO::FETCH_OBJ );
$db = null; // clear db object
echo json_encode( $users );
} catch( PDOException $e ) {
echo '{"error": {"msg": ' . $e->getMessage() . '}';
}
});
I read about several options but i can't understand how all this works. How i get data from forms for example and pass to route and route output the result that i want using data from forms.
Can you suggest me a simple way to do that and all the framework that i need?
If you want a UI (user interface) then you need to build a front-end application - written in Javascript assuming it would be a web front-end (perhaps using one of the popular frameworks such as React or Angular) - which can then make calls to your API via AJAX requests to get data to populate the screens etc. Or you could make almost any other type of application to talk to it
Your API is the backend...it can support having lots of different types of application calling it potentially (e.g. web app, mobile app, desktop app, automated service, IoT device etc) - that's the beauty of separating the core, shared functionality and logic of your system into an API, away from the potential different client-side experiences you might decide to create.
Related
So I have a RESTful API, but I want to be safe so that not everyone can do anything.
$app->get('/users' , function(Request $request, Response $response){
$sql = "SELECT * FROM users";
try{
// Get db object
$db = new db();
// Connect
$db = $db->connect();
$stmt = $db->query($sql);
$users = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo json_encode($users);
} catch(PDOException $e){
echo '{"error": {"text": '.$e->getMessage().'}}';
}
});
So when i go to http://localhost/API/users i get all users into a json table.
Inside my database my data are stored like [{"id":"1","username":"werknemer","password":"...","level":"1","name":"piet","surname":"jan","email":"pietjan#gmail.nl"}]
I would like everyone to see his own table through my API and if you are level 5.
Is there a solution for that?
Your example is pretty basic and it's a starting point for using some "auth" concept in your REST APIs.
First things first: Authentication != Authorization.
Split these two concepts, the first one is going to make a user registered and logged into your app, the second one makes the "hard work" that you are looking for in this example, so check if a specific user is able to do some stuff.
For authentication, you can provide all the methods that you want, but remember that in REST your app MUST be stateless and you should provide a token (passed via HTTP Headers) that will be used by your application for understanding if the user is LOGGED and CAN do some stuff.
That's the key concept: A token (see JWT or OAUTH) should be used for authorization, and a very basic authorization is: "USER LOGGED".
In your example, you should use the middlewares for filter the http request, and don't enter into the router callback if the user is not authorized (logged in || have not a minLevel:5).
Checkout JWT or OAuth2 for this kinda stuff for more info.
Check this out -> (https://github.com/damianopetrungaro/slim-boilerplate) for a basic example of JWT generation in a slim app (if you are going to use this boilerplate PLEASE do not use the md5 for hash password this is a pretty basic example)
You need to add authentication and then authorisation to your API.
Authentication is the process of knowing who is accessing the API. A good way to do this is to you OAuth 2. I like and use Brent Shaffer's OAuth 2.0 Server library. https://github.com/akrabat/slim-bookshelf-api/tree/master/api contains an implementation of an API that using OAuth 2 to authorise users.
Once you know who is logging in, you then need to limit their access based on their role (or level). This is called access control. I like the zend components for this. Try zend-permissions-rbac - there's a good article on how to use it on the ZF blog.
I have been experimenting with Slim for a few days now and there is a lot that I like. However, there is one thing that nags me - when Slim is used to build a REST API it insists on putting everything into one single .php file - or even worse, a load of anonymous functions (one for each exposed REST method).
This works, that is not the issue. However, does it not mean that when used for building any but the most trivial of APIs you are imposing an unnecessary burden on the server by getting it to load and parse a potentially really big PHP file when only a tiny percentage of its code is relevant?
If yes, then it begs the next question - I am a newbie to micro frameworks - is there a micro framework that does things in a way that avoids this issue?
I'm unsure whether you are looking for a framework for a complete website or for an api alone. If latter I can recommend restler, which is a very simple, OO and stable package for developing API's.
On the other hand Laravel has built in resource controllers to ease the api development, it also has a very fast growing community.
If you're looking for both a website framework ánd an api framework in one, my guess is it will be very difficult combining that into one micro framework. Laravel/Symfony and other frameworks will eventually be needed especially if you expect growth in the project.
I made a REST API using AltoRouter:
http://altorouter.com/
I like the fact that after one route matches I can choose how to make the call, so I can point to the folder where I have all the REST controllers divided in several well organized files.
http://altorouter.com/usage/processing-requests.html
An example:
function rest_data($data, $format)
{
header("Cache-Control: no-cache, must-revalidate");
header("Expires: 0");
header('Content-Type: ' . $format);
if (is_object($data) && method_exists($data, '__keepOut'))
{
$data = clone $data;
foreach ($data->__keepOut() as $prop)
{
unset($data->$prop);
}
}
$options = 0;
$json=json_encode($data, $options);
echo $json;
}
$router = new AltoRouter();
$router->setBasePath('/rest');
$router->map('GET|POST','/', 'home#index', 'home');
$router->map('GET','/sample_users/all', 'sample_user#all', 'sample_users_get');
// match current request
$match = $router->match();
if($match && $match['name']=='home')
{
// write some intro
exit();
}
if($match)
{
$target=$match['target'];
list($class_name,$function_name) = explode("#",$target);
require($conf["src.path"].'/rest/'.$class_name.'.php');
foreach($_GET as $k=>$v) $match['params'][$k] = $v;
$controller = new $class_name;
$res = $controller->$function_name($match['params']);
rest_data($res,RestFormat::JSON);
}
If you are not so keen on the Slim PHP framework might I suggest something like Symfony ? Personally I like the way Slim works, and suits what I need to build right down to a T - however I can see your frustration with creating a RESTful solution. Symfony on the other hand breaks things up a little more so you have less fat controllers.
If Symfony isn't right for you I guess you could pull out a heavyweight ike Laravel?
I am working on one project where following things are expected,
To write a web service to get users list and individual users information
To write a web service to do CRUD operations.
I understand that GET method will be useful for fetching information and execution of that API call via browser but can any one help me for following items?,
To make API call if I want to use "PUT", or "POST" or "DELETE" methods? How to do it via browser? or what would be best way to do it?
I have to use Stored procedure to fetch the information from DB for GET method?
I suggest you to use a slim Php microframework, it provides a powerful, extensible framework for building a REST API.
So, The typical REST conventions for URL requests you'll use:
GET /items: Retrieve a list of items
GET /items/22: Retrieve item 22
POST /items: Create a new item
PUT /items/22: Update item 22
DELETE /items/22: Remove item 22
Slim's URL router will help you to make it easier.
And YES, you have to create your data object to fetch from server's side, one tipycall example to get it:
// handle GET requests for /articles/:id
$app->get('/items/:id', function ($id) use ($app) {
try {
// query database for single items
$items = R::findOne('items', 'id=?', array($id));
if ($items) {
// if found, return JSON response
$app->response()->header('Content-Type', 'application/json');
echo json_encode(R::exportAll($items));
} else {
// else throw exception
throw new ResourceNotFoundException();
}
} catch (ResourceNotFoundException $e) {
// return 404 server error
$app->response()->status(404);
} catch (Exception $e) {
$app->response()->status(400);
$app->response()->header('X-Status-Reason', $e->getMessage());
}
});
Finally, this tutorial may help you to a total work around
[http://www.androidhive.info/2014/01/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-12-2/][1]
I'm creating a project which uses CakePHP framework, and the PHP OAuth module.
The reason I'm using the module over a Vendor plugin is because the APIs need to have data/custom headers sent to them or else they generate 500s, and I know the standard PHP module does this well.
The issue is that when I use OAuth->fetch("http://www.example.com" ...), CakePHP redirects the external fetch request to my localhost (which I'm developing on), thus resulting in no data being generated.
It looks like the only way I can get external data is by using CakePHP's HTTPSocket class, but that doesn't allow me to send that data I need to send to the OAuth provider.
Does anyone know how to turn off this routing, or if I should be doing something differently?
UPDATE : Currently code is as follows:
public function createClient() {
$client = new OAuth(
'key',
'secret'
);
$client->disableSSLChecks();
if ($accessToken = $this->getAccessToken() !== false) {
$client->setToken(
$accessToken[$this->accessTokenKeyKeyname],
$accessToken[$this->accessTokenSecretKeyname]
);
}
return $client;
}
$url = 'http://example.com';
$client = $this->createClient();
$client->fetch($url, null, OAUTH_HTTP_METHOD_GET);
The request/access tokens are generated successfully, but the fetch continues to redirect to localhost, instead of example.com (example.com being used as an example URL).
I'm working on a solution to make certain data from a large database available to a remote website. My first thought was to simply cook up some soap web services to fetch certain data from the database. This could be done in just a few line, for instance like this, with the user of Zend_Soap_Server:
class MyClass
{
public function getlastname($id)
{
$dbh = new PDO("oci:dbname=bigdb", "theuser", "thepass");
$stmt = $dbh->prepare("select lastname from person where id = :id");
if ($stmt->execute(array(':id',$id)))
{
$row = $stmt->fetch();
return $row['lastname'];
}
}
}
$server = new Zend_Soap_Server(null, $options);
$server->setClass('MyClass');
$server->setObject(new MyClass());
$server->handle();
Now someone told me to also have a look at message brokers / queues. I've been taking a look at some software like apache activeMQ, stomp and zend_queue but I didn't really get a clear view what they should be used for and weather they would be useful in this project.
I do understand that my implementation could have some drawbacks, like a sluggish website when the database is not responding quickly and a high load on the database when there are coming lots of requests from the website, would a message broker be able to prevent such complications?
The role of a message broker is to check the requests and dispatch them to the right service or return a response from a cache.
If you are expecting large traffic you probably should consider using a message broker.
Regards,
Alin