nathggns / scaffold Goto Github PK
View Code? Open in Web Editor NEWLightweight PHP API Framework
License: Other
Lightweight PHP API Framework
License: Other
A popular usage model for api-first applications is to have a class based interface for their application.
<?php
$users = Scaffold::get('/users/nathaniel');
$user = Scaffold::post('/users', array(
'username' => 'claudio',
...
));
I've got a few ideas for how to make this possible, but I'm posting it as an issue first to see what you think.
For future-compatibility purposes, we should never manually initiate a class, instead, we should always use the Service class. However, if you attempt to create a class for a service that hasn't manually been registered, you will get an exception.
Instead, I think it should make a class that refers to the service name you passed, using 'new'.
We should be able to specify functions that transform data being saved to a user. This, for example, would allow you to automatically hash passwords, or capitalize names for users.
What do you think?
Router::prepare_route
does not account for the '-' character when using \w
.
Somehow we need to handle exceptions.
I propose a system similar to this.
I propose an exception handler sort of system.
Single Exception
<?php
$router->error('ExceptionValidate', function($e) {
// ...
});
Multiple Exceptions
<?php
$router->error(['ExceptionValidate', 'ExceptionRouting'], function($e) {
// ...
});
All Exceptions
<?php
$router->error(true, function($e) {
// ..
});
Where $e
is an object allowing you to decide what to do.
<?php
$e->rethrow(); // Re-throw the error. (Eventually this will be catched by the Error class, which is yet to be made.
$e->send($val); // Send value.
$e->exc // The actual exception
Simple router with automatic and custom routes.
This needs to be configurable. For example, E_NOTICE
should not cause the whole damn thing to die.
I really think response should send metadata along with the response:
{
"speed": 0.1234,
"version": 1.0,
"status": 200,
"response": {
"message": "Hello, World"
}
}
As opposed to
{
"message": "Hello, World"
}
We need to implement Model->import. It can accept any pre-existing Model, or you can simply give it an array.
<?php
$user = new ModelUser();
$user->read(1);
$file = new ModelFile('users.json');
$file->import($user);
$file->save();
$file = new ModelFile('users.json');
$file->import(array('username' => 'foo'));
$file->save();
Add tests, for everything. Without exceptions. Well, yes, with exceptions, but ... you know what I mean.
With the default route service, you can't do a specific method for GET requests, and another for POST requests to the same URL.
In order to retain the "lightweight" description, we need to make some modifications. It's actually pretty hefty at the moment.
One thing that would certainly become a module is the database side, which includes the following classes.
ModelDatabase
DatabaseDriverPDO
DatabaseDriverInterface
DatabaseDriverSqlite
DatabaseDriver
DatabaseBuilderInterface
DatabaseBuilderSql
DatabaseBuilderSqlite
DatabaseBuilder
Database
Every driver and builder would be its own module, apart from SQL
,SQLite
and PDO
.
However, there are some other classes that could become parts of a module too, namely:
Validate
There are some others that aren't necessarily core classes, but could be needed by the core:
Inflector
Error
Shutdown
Dummy
Dynamic
A default error class to send a '500 Internal Server Error' response when an error is encountered.
Nat told me to put my idea in an issue, so: I think it would be great to have an optional statistics feature as people like to know how much their service is being used, it's also something cool to shout about.
At the moment, the foreign_key will always be matched with id (let's call this the local_key). We need to be able to choose the local_key.
This should help.
Currently the router uses the first matched route, which can create issues with something like this.
<?php
$router->all('/:controller/:id');
$router->all('/download/:name/:version', 'download', ['version' => 1]);
If you pass a URL such as /download/project/1
to that, it will match the second route, which is fine, but if you pass '/download/project' to it, it will match the first route, which is problematic if you expect $request->params['version']
to be set.
Even if you change the encoding function, the content-type will always be application/json.
I've been considering it. Should a Validate
test end after the first error?
We need to add comments all over Scaffold, preferably with DocBlock
syntax.
Comment every class that you made, and if you feel you have sufficient understanding of another class, comment that too.
We should be able to use models as controllers in Scaffold. This would include standard add/delete/update as routes.
You would be able to control the response and add certain conditions that would need to be fulfilled in order to complete the request.
You would also be able to transform the response.
Model->find
is the way of finding an item without knowing it's specific id. It takes an array configuring it.
<?php
$user = new ModelUsers();
$user->find(array(
'where' => array(
'username' => 'nathaniel'
),
'limit' => 1,
'order' => 'User.id' // same as array('User.id', 'ASC')
);
// You can also use some shorthand functions for find
$user
->where('username', 'nathaniel') // same as ->where(array('username' => 'nathaniel'))
->limit(1)
->order('User.id') // same as order('User.id', 'ASC')
->find();
The where bit is a bit difficult though. How do we specify "OR" instead of "AND", how do we say ">" or "<"?
<?php
$user->where('username', array('nathaniel', 'claudio')); // OR
Sometimes you want config sections to merge with default, but sometimes you don't. Right now (on my local repo), to indicate merging, you can do something like this.
<?php
return [
'default' => [...],
'other' => Service::get('config')->merge('default', [...])
];
However, that isn't too nice. Another solution could be that the class that asks for the config defines merging.
<?php
Service::get('config')->get('core', ['merge' => true]);
// or
Service::get('config')->get('core', ['merge' => ['default']);
// or
Service::get('config')->get('core', true);
// or
Service::get('config')->get('core', 'default');
// or
Service::get('config')->get('core', [true]);
// or
Service::get('config')->get('core', ['default']);
And if we wanted to stick with merging in the config file, could it be something like this?
<?php
return Service::get('config')->merge('default', [
...
]);
// The first parameter here is equivalent to the second in the previous example
The inline PHPDoc blocks should be extended so an API documentation can be generated from the source code. A separate guide should introduce new users to the framework and all of its components.
Allow the application to do something like
class Database { use DatabaseQueryBuilderSQL; use DatabaseDriverPDO; }
I did start writing this but I got stumped so I'm leaving myself an issue to get it done.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.