Skip to content

Commit

Permalink
Add support for restful API
Browse files Browse the repository at this point in the history
  • Loading branch information
ngekoding committed May 21, 2021
1 parent b9d8a7d commit b5f80ab
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 5 deletions.
18 changes: 14 additions & 4 deletions README.md
Expand Up @@ -4,16 +4,14 @@ Just a basic example how to integrating CodeIgniter 3 + Vue.js 3 + Vite with sup

If you loves CodeIgniter 3 & Vue.js, you must try this one to make your life easier!

Some changes to make this works!

**Some changes to make this works!**
1. application/helpers/vite_helper.php
2. application/controllers/Vue.php
3. application/config/routes.php
4. application/views/index.vue.php
5. frontend/vite.config.js

# Running the project

## Running the project
1. Setting CodeIgniter base_url at application/config/config.php
2. Open Terminal/CMD and enter to ```frontend``` directory
3. Install vue project dependencies: ```npm install```
Expand All @@ -22,4 +20,16 @@ Some changes to make this works!
6. Open the browser and go to the project address, e.g. ```http://localhost/codeigniter3-vuejs3-vite-boilerplate/```
7. Enjoy!

## Features / ideas

I try to keep this project as simple as possible, so you can making a changes to suit your needs. No need to install a bunch of libraries for making something simple.

### Restful API support: response helper, ajax request validation ✅
- application/config/routes.php
- application/core/MY_Controller.php
- application/controllers/api/*

### Middlewares
- Not implemented yet!

Powered by [ngekoding.github.io](https://ngekoding.github.io)
13 changes: 13 additions & 0 deletions application/composer.json
@@ -0,0 +1,13 @@
{
"name": "ngekoding/codeigniter3-vuejs3-vite-boilerplate",
"description": "CodeIgniter 3 + Vue.js 3 + Vite with supported Hot Module Replacement (HMR)",
"type": "project",
"license": "MIT",
"authors": [
{
"name": "Nur Muhammad",
"email": "blog.nurmuhammad@gmail.com"
}
],
"require": {}
}
9 changes: 8 additions & 1 deletion application/config/routes.php
Expand Up @@ -57,5 +57,12 @@
* Vue Routes
* All routes with 'site' prefix will used by Vue
*/

$route['^site?(.+)'] = 'vue';

/**
* We will use manual routes only for the API calls
* We also defined spesific HTTP methods
*/
$route['api/v1/users']['GET'] = 'api/v1/user';
$route['api/v1/users/(:num)']['GET'] = 'api/v1/user/show/$1';
$route['api/(.*)'] = '404';
42 changes: 42 additions & 0 deletions application/controllers/api/v1/User.php
@@ -0,0 +1,42 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class User extends MY_Controller {

// All method must called by ajax request
protected $ajax_request_only = TRUE;

// Just example data
// In the real case, this data from the DB
private $users = [
['id' => 1, 'name' => 'Nur Muhammad'],
['id' => 2, 'name' => 'Nabil Muhammad Firdaus'],
['id' => 3, 'name' => 'Resqa Dahmurah'],
['id' => 4, 'name' => 'Dian Febrianto'],
];

public function __construct()
{
parent::__construct();
}

public function index()
{
$this->send_success_response($this->users);
}

public function show($id)
{
$found = array_search($id, array_column($this->users, 'id'));

if ($found !== FALSE) {
$user = $this->users[$found];
$this->send_success_response($user);
}

$this->send_response([
'success' => FALSE,
'error' => 'There is no user with the given ID.'
], self::HTTP_NOT_FOUND);
}
}
112 changes: 112 additions & 0 deletions application/core/MY_Controller.php
@@ -0,0 +1,112 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

const HTTP_OK = 200;
const HTTP_CREATED = 201;
const HTTP_NOT_MODIFIED = 304;
const HTTP_BAD_REQUEST = 400;
const HTTP_UNAUTHORIZED = 401;
const HTTP_FORBIDDEN = 403;
const HTTP_NOT_FOUND = 404;
const HTTP_METHOD_NOT_ALLOWED = 405;
const HTTP_NOT_ACCEPTABLE = 406;
const HTTP_UNPROCESSABLE_ENTITY = 422;
const HTTP_INTERNAL_ERROR = 500;

/**
* Defining if the request must an ajax request
*
* Boolean: affecting to all methods
* Array: affecting only the specified methods
*/
protected $ajax_request_only = FALSE;

public function __construct()
{
parent::__construct();

$this->ajax_request_validator();
}

private function ajax_request_validator()
{
$error = FALSE;
$is_ajax_request = $this->input->is_ajax_request();

if ($this->ajax_request_only === TRUE && !$is_ajax_request) {
$error = TRUE;
} elseif (is_array($this->ajax_request_only)) {
// Make checking with case insensitive
$ajax_request_only = array_map('strtolower', $this->ajax_request_only);

// Get current requested method
$requested_method = $this->router->fetch_method();

if (!$is_ajax_request &&
!empty($ajax_request_only) &&
in_array(strtolower($requested_method), $ajax_request_only)
) {
$error = TRUE;
}
}

if ($error) self::send_bad_request('Ajax request only!');
}

public static function send_response($data, $response_code = self::HTTP_OK)
{
http_response_code($response_code);
header('Content-Type: application/json');
echo json_encode($data);
exit;
}

public static function send_success_response($payload = FALSE)
{
$data['success'] = TRUE;

if ($payload !== FALSE) {
$data['data'] = $payload;
}

self::send_response($data, self::HTTP_OK);
}

public static function send_unprocessable_entity($payload = FALSE)
{
$data['success'] = FALSE;
$data['error'] = 'Unprocessable Entity';

if ($payload !== FALSE) {
$data['data'] = $payload;
}

self::send_response($data, self::HTTP_UNPROCESSABLE_ENTITY);
}

public static function send_internal_server_error($error_message = FALSE)
{
$data['success'] = FALSE;
$data['error'] = 'Internal Server Error';

if ($error_message !== FALSE) {
$data['error'] = $error_message;
}

self::send_response($data, self::HTTP_INTERNAL_ERROR);
}

public static function send_bad_request($error_message = FALSE)
{
$data['success'] = FALSE;
$data['error'] = 'Bad Request';

if ($error_message !== FALSE) {
$data['error'] = $error_message;
}

self::send_response($data, self::HTTP_BAD_REQUEST);
}
}

0 comments on commit b5f80ab

Please sign in to comment.