Table of contents
Clone this repo into our project, change the folder name to api and done.
Using this boilerplate, we're going to work on setup folder frequently.
* app
	* private   # Main drivers of boilerplate are located
	* setup     # APIs, Database Configuration, Models, Routes etc.
		* apis		
		* composer
		* helpers	
		* configs
		* models
* public        # We can place assets and upload your static files here The routes are located at app\setup\routes.php
/** By `REQUEST_METHOD` routes */
$routing->get("url", "classAPI::method");
$routing->post("url", "classAPI::method");
$routing->put("url", "classAPI::method");
$routing->delete("url", "classAPI::method");
/**
 * Auto routing `REQUEST_METHOD`
 * This is equal to
 * $route->get("url", 	"class::get");
 * $route->post("url", 	"class::post");
 * $route->put("url", 	"class::put");
 * $route->delete("url", class::delete");
 */
$routing->auto("url", "classAPI");
/** With parameter/s URL */
$routing->get("url/:id", "classAPI::method");Our APIs that will process our request will be in the app\setup\apis, every api will extend to Api class which will help us to load models, make responses, and verify CSRF tokens.
class TestAPI extends Api{
	public function get(){}     # GET Request
	public function post(){}    # POST Request
	public function put(){}     # PUT Request
	public function delete(){}  # DELETE Request
	public function foobar(){}  # CUSTOM method
	# For, with parameters URL, we have several ways
	# First, we can access it from Api class
	public function choiceOne(){
		$this->id; // (string)
	}
	# Second, from argument
	# $params is an object containing the parameters
	public function choiceTwo($params){
		$params; // (object)
		$params->id; // (string)
	}
	/**
	 * Handling Request Parameters
	 * Sample data:
	 * {
	 * 	"username": "foobar",
	 * 	"email": "[email protected]"
	 * } 
	 **/
	public function handlingRequest(){
		# Access by Property
		# Throw error if the request doesn't exist
		$this->request->username;
		$this->request->password;
		# Access by method
		# Return null if doesn't exist
		$this->request("password");
	}
}API class comes with simple methods that can help speed up our development.
class TestAPI extends Api{
	public function foobar(){
		# Terminate the request when not using `POST` request
		$this->expectMethod("POST");
		# Return CSRF token
		# You can pass `true` to refresh csrf token
		$token = $this->csrfGetToken();
	}
}To interact with MySQL database, we need to create a model that can connect to database and perform queries. Each model will extends to Model class, that will give us some simple pre-defined methods such as get, insert, update, and delete.
First we need to update some configuration to properly connect to MySQL.
Go to app\setup\configs\config.php and update the following values.
define('DB_HOSTNAME', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_NAME', 'nap');To create a model, go to models, create a model that extends to Model class.
class Task extends Model{
}Next, create a constructor to define our table, specify the table name using table_name property, and table columns using table_columns property.
class Task extends Model{
	function __construct(){
		$this->table_name = "tasks";
		$this->table_columns = ["id", "title", "content"];
	}
}To use model into our API, we can load model using model() method that is part of API class.
class TaskAPI extends Api{
	 # Load `Task` model
	function __construct(){
		$this->taskModel = $this->model("Task");
	}
	
	# Return data
	public function get(){
		$this->taskModel->get("taskID");
	}
	# Insert new data
	public function post(){
		$this->taskModel->insert([
			"title" => "Take a Nap",
			"content" => "Let's rest"
		]);
	}
	# Update existing task
	public function put(){
		$this->taskModel->update([
			"title" => "Take a Nap (edited)",
			"content" => "Let's take a rest part 2"
		], [ # This second parameter is the condition
			"id" => "taskID"
		]);
	}
	# Delete existing task
	public function delete(){
		$this->taskModel->delete("taskID");
	}
}Login and registration are two of the most important parts of your application, if necessary. NAP provides a basic authentication boilerplate that you can start with, and that also extends to Model class.
To use the authentication boilerplate, you can just rename the Authentication.php located in the models folder, or duplicate it based on your needs.
The boilerplate is just a plain session-based authentication that you can rewrite if you want or create your own authentication class.
Authentication Boilerplate includes.
/**
 * First array is the data to be inserted
 * Second is the keys that need to be unique
 */
$this->Authentication->register([
	"username"	=> $this->request->username,
	"password"	=> $this->request->password
], [
	"unique"	=> ['username']
]);
# Login
$this->Authentication->login("username", "password");
/**
 * Check status if logged or not
 * Pass `true` to terminate the script if you are not logged in.
 */
$this->Authentication->guarded();
# Logout
$this->Authentication->logout();Checking for values can become exhaustive. That can create a bunch of nested conditional statements.
The validation class is enabled by default in the boostrap.php in the app folder. To use the validation class, pass the items with their checks to the first parameter, and pass a boolean to the second parameter to set if the validation will automatically terminate the script if there's an invalid check.
As an example, let's put a validation on the AuthAPI login.
public function login(){
	new Validate([
		[
			# The value to be check
			"value" => $this->request("username"),
			# The key of this item when it is converted as an object
			"key"	=> "username",
			# The label on error
			"label"	=> "Username",
			# Several checks to be perform, separated by pipe "|"
			"checks" => "required|min:3|max:50"
		],
		[
			"value" => $this->request("password"),
			"key"	=> "password",
			"label"	=> "Password",
			"checks" => "required|min:8|max:150"
		]
	], true);
	$return = $this->Authentication->login($this->request->username, $this->request->password);
	$this->json([
		"status"	=> $return['success'],
		"message" 	=> $return['message']
	]);
}