การใช้งาน CURLRequest เรียกใช้งาน API ใน CodeIgniter 4

บทความใหม่ เดือนที่แล้ว โดย Ninenik Narkdee
restful api curlrequest codeigniter 4 codeigniter

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ restful api curlrequest codeigniter 4 codeigniter



ในสามหัวข้อบทความที่ผ่านมา เราพูดถึงการกำหนด
และใช้งาน RESTful API ซึ่งเป็นการจัดการของทาง
ฝั่ง Server เนื้อหาในบทความนี้ เราจะพูดถึงการเรียกใช้งาน
API จากฝั่ง Client หรือฝั่งที่ต้องการใช้งานข้อมูล API
ที่ได้สร้างไว้แล้ว
    โดยทั่วไป เราจะคุ้นกับรูปแบบการกำหนด หรือการใช้งาน
คำสั่ง CURL ในการเรียกใช้งาน API หรือส่งค่าข้อมูลไปบันทึกผ่าน API
และสำหรับ CI4 ก็มี Library ที่มีชื่อว่า CURLRequest ที่ให้เราสามารถกำหนด
และเรียกใช้งาน API ได้อย่างสะดวกด้วยวิธีที่ง่าย โดยไม่จำเป็นต้องติดตั้ง
package หรือ Library อื่นเพิ่มเติม
 
 
 

เตรียมส่วนของไฟล์ทดสอบ

    เช่นเดิม เราจะเตรียมส่วนของ Controller สำหรับทดสอบแนะนำการใช้งาน ดังนี้
 
    app/Controllers/Helloworld.php
 
<?php namespace App\Controllers; 
use CodeIgniter\Controller; // เรียกใช้งาน Controller class
class Helloworld extends Controller 
{
    public function index() 
    {  

    }
}
 
    ในการจำลองการทดสอบใช้งาน สามารถใช้ RESTful API ตามลิ้งค์ด้านล่าง
    https://jsonplaceholder.typicode.com/
 
 
 

การเรียกใช้งาน CURLRequest

    เราสามารถเรียกใช้งาน CURLRequest ได้ใน 2 รูปแบบ ดังนี้
 
$client = \Config\Services::curlrequest();
// หรือ
$client = service('curlrequest');
    
    กรณีมีการกำหนด option เพิ่มเติม จะกำหนดในลักษณะดังนี้
 
$options = [
        'baseURI' => 'http://example.com/api/v1/',
        'timeout'  => 3
];
$client = \Config\Services::curlrequest($options);
// หรือ
$options = [
        'baseURI' => 'http://example.com/api/v1/',
        'timeout'  => 3
];
$client = service('curlrequest',$options);
 
    การกำหนด option เข้าไปในขั้นตอนการเรียกใช้ เหมือนเป็นการกำหนดค่า default ที่จะใช้
กับ instance ค่านี้ไปตลอด โดยไม่ต้องกำหนดค่าซ้ำ แต่ถ้าต้องการ override ค่าเป็นค่าอื่น
สามารถใช้คำสั่ง setHeader() เปลี่ยนแปลงค่าเป็นค่าใหม่ได้
    ในที่นี้เราจะใช้แบบ service ฟังก์ชั่น
 
 
 

คำสั่งและการใช้งาน CURLRequest

    ในการทำงาน HTTP Request เราสามารถใช้งานคำสั่งได้ใน 2 แบบคือ ใช้คำสั่ง request() หรือใช้
คำสั่งตามชื่อ HTTP Method ได้แก่ get() delete() head() options() patch() put() และ post() 
    ตัวอย่างแบบแรก
 
$client->request('GET', 'https://api.github.com/user');
 
    ตัวอย่างแบบที่สอง
 
$client->get('http://example.com');
$client->delete('http://example.com');
$client->head('http://example.com');
$client->options('http://example.com');
$client->patch('http://example.com');
$client->put('http://example.com');
$client->post('http://example.com');
 
    รูปแบบที่สองเหมือนกับการเขียนแบบย่อ ที่เอา HTTP Method มากำหนดค่าเฉพาะไปเลย
ว่าเป็นการ request() ด้วย method ใด ทำให้เขียนได้กระชับขึ้น
    ทั้งสองรูปแบบยังรองรับการกำหนด parameter option เพิ่มเติม ในรูปแบบดังนี้
 
$client->request('GET', 'https://api.github.com/user', [
        'auth' => ['user', 'pass']
]);
// หรือ
$client->get('https://api.github.com/user', [
        'auth' => ['user', 'pass']
]);
 
 

    การกำหนด Base URI

    เราสามารถกำหนด Base URI สำหรับใช้งานการระบุ URL ของ API ให้กระชับหรือสั้นลงได้ เช่น กรณี
URL ของ API นั้นๆ เราต้องใช้ซ้ำๆ การกำหนดแบบ ยาวๆ ทุกครั้งอาจจะไม่สะดวกในการใช้งาน ดังนั้น
ในขั้นตอนการเรียกใช้ เราก็ระบุส่วนของ URL หลัก หรือ Base URI ประมาณนี้เข้าไปได้
 
$options = [
        'baseURI' => 'https://api.github.com'
];
$client = service('curlrequest',$options);
$client->get('/user', [ 'auth' => ['user', 'pass']]);
 
    จะเห็นว่า path ของ URL ที่เรากำหนด จะเหลือแค่ส่วนของ '/user' เพราะเรากำหนด Base URI ไปแล้ว
โค้ดก็จะกระชับ เราก็ไม่ต้องกำหนด URL ยาวๆ ซ้ำๆ อีก
    การกำหนด base URI และการกำหนด URI ในคำสั่งที่ทำการ request จะมีผลกับ URL สุดท้ายของ API
    ดูตารางเปรียบเทียบเป็นแนวทาง
 
 

 
 
    สังเกตว่า เครื่องหมาย / มีผลต่อผลัพธ์สุดท้ายของ URL  เช่น อาจจะแทนที่ค่า URI เดิม หรือต่อจาก 
URI เดิม หรือแม้แต่การกำหนด URL เต็มเข้าไป ก็จะเหมือนกันแทนที่ URL ทั้งหมด เป็นต้น ให้ลองทำ
ความเข้าใจรูปแบบจากตาราง
 
 

    การกำหนด Request Options

    ในการทำ request ไปยัง API เราสามารถกำหนด option เพิ่มเติมได้ดังนี้
 
    allow_redirects
    สำหรับอนุญาตการ request รองรับการ redirect ของ api เช่น URL เปลี่ยนจากที่หนึ่งไปอีกทีหนึ่ง
ตัว request ก็จะเปลี่ยนไปยัง URL สุดท้ายของ API   โดยค่าเริ่มต้นเป็น true คือ รองรับการ redirect
หรือหากต้องการกำหนด การรองรับการ redirect แบบมีเงื่อนไขเพิ่ม ก็สามารถกำหนดค่าต่างๆ เหล่านี้ได้
 
$client->get('/users', ['allow_redirects' => [
        'max'       => 10,
        'protocols' => ['https'] 
]]);
// ค่าที่สามารถกำหนดเพิ่มเติม
'max'       => 5, // จำนวน redirect สูงสุดก่อนหยุด
'strict'    => true, // ให้ตัวแปร POST สามารถส่งต่อๆ ไปในการ redirect ได้
'protocols' => ['http', 'https'] // กำหนด หรือจำกัด protocal ที่จะ redirect ได้
 
    กรณีไม่ต้องการให้รองรับการ redirect ให้กำหนดค่าเป็น fasle ประมาณนี้
 
$client->get('/users', ['auth' => ['username', 'password', 'basic']]);
 
 
    auth
    บาง API มีการจำกัดสิทธิ์การเข้าถึง หรือสิทธิ์การใช้งานไว้ ในกรณีนี้คือใช้รูปแบบ 
Basic Authentication ที่เราได้แนะนำไปในบทความตอนที่แล้ว http://niik.in/1015
    และแบบ Digest Authentication ทั้งสองรูปแบบ จะสามารถกำหนดการ request โดยเพิ่มในส่วน
ของ auth เป็น option เพิ่มเติมได้ดังนี้
 
$client->get('/users', ['auth' => ['username', 'password', 'basic']]);
 
 
    body
    ใช้สำหรับกำหนดส่วนข้อมูลที่จะส่งไปกับการ request ปกติใช้กับ PUT และ POST method 
สำหรับการกำหนดส่วนของ body จะสามารถทำได้ในสองรูปแบบ คือใช้คำสั่ง setBody() กับ การกำหนด
options เข้าไป
 
$client->setBody($body)->post('/users');
// หรือ 
$client->post('/users', ['body' => $body]);
 
    cert
    บาง API มีการตรวจสอบความถูกต้องของใบ certificate ของฝั่ง client เช่น API มีไฟล์ certificate
ให้เฉพาะผู้ใช้ หรือ client ที่มีไฟล์ certificate ที่จะสามารถเข้าใช้งานได้ ก็จะกำหนดในลักษณะดังนี้
 
$client->get('/users', ['cert' => ['/path/getServer.pem', 'password']);
 
 
    connect_timeout
    การกำหนดเวลาที่ต้องรอสำหรับการพยายามเชื่อมต่ออีกครั้งไปยัง API กำหนดค่าเป็นหน่วนมิลลิวินาที
หรือหากไม่ต้องการกำหนด สามารถระบุค่าเป็น 0 ได้
 
$client->get('/users', ['connect_timeout' => 0]);
 
 
    cookie
    ใช้สำหรับกำหนดค่าของ CURLOPT_COOKIEJAR เป็น path ของ cookie ไฟล์ ทีเราต้องการจะเก็บ
cookie ที่ server ที่เรา request ไปส่งค่ากลับมาด้วย  และใช้กำหนดค่า CURLOPT_COOKIEFILE เป็น
path ของ cookie ไฟล์ที่เราจะส่ง cookie ไปยัง server ที่เรา request ไป  ซึ่งปกติก็จะใช้ไฟล์เดียวกัน
 
$client->get('/users', ['cookie' => WRITEPATH . 'CookieSaver.txt']);
 
 
    delay
    ใช้กำหนดเวลาที่ต้องรอก่อนที่จะส่ง request ไปยัง API กำหนดเป็นหน่วยมิลลิวินาที
 
// รอ 2 วินาที แล้วค่อส่ง request ไป
$client->get('/users', ['delay' => 2000]);
 
    form_params
    เราสามารถส่งข้อมูลในรูปแบบคล้ายฟอร์มไปยัง server หรือที่เราคุ้นกันนรูปแบบการส่งข้อมูลใน
HTML Form ปกติ ที่มีค่า enctype เท่ากับ application/x-www-form-urlencoded โดยกำหนดค่า
ใน form_params options ประมาณนี้
 
$client->post('/users', [
        'form_params' => [
                'name' => 'demo',
                'email' => 'demo@example.com'
        ]
]);
 
    คำสั่งข้างต้นจะกำหนดค่า Content-Type header เป็น application/x-www-form-urlencoded
 
 
    headers
    ใช้สำหรับกำหนด header ซึ่งเราสามารถใช้คำสั่ง setHeader() แทนได้ ดูตัวอย่างการกำหนด
แบบใช้ option และแบบใช้คำสั่ง setHeader() ตามตัวอย่างด้านล่าง
 
$client->get('/users', [
        'headers' => [
                'User-Agent' => 'testing/1.0',
                'Accept'     => 'application/json',
                'X-Foo'      => ['Bar', 'Baz']
        ]
]);
// แบบคำสั่งเหมาะกับการกำหนดทีละค่า
$client->setHeader('Accept', 'application/json')->get('/users');
// หรือถ้ากำหนดหลายค่า ก็ให้เรียกใช้งานต่อเนื่องได้ได้
$client->setHeader('User-Agent', 'testing/1.0')
->setHeader('Accept', 'application/json')
->setHeader('X-Foo', ['Bar', 'Baz'])
->get('/users');
 
 
    http_errors
    โดยปกติเมื่อทำการ request โดยใช้งาน CURLRequest หากมีข้อผิดพลาดเกิดขึ้น หรือมี HTTP 
Code มากกว่า 400 จะไม่คืนค่าส่วนของเนื้อหาหรือ body ข้อมูลใดๆ กลับมาก แต่เราสามารถกำหนดให้
สามารถคืนค่าเป็นรูปแบบข้อความที่ต้องการได้ โดยกำหนด http_errors option ในลักษณะดังนี้
 
$response = $client->get('/status/500', ['http_errors' => false]);
echo $response->getStatusCode(); // 500
 
 
    json
    การกำหนดค่า json option เป็นวิธีที่สะดวกวิธีหนึ่งที่ใช้สำหรับส่งข้อมูลในรูปแบบ JSON data ไปใช้งาน
โดยจะทำการกำหนดส่วนของ Content-Type header เป็นค่า application/json ให้อัตโนมัติ รูปแบบข้อมูล
ที่จะส่ง จะต้องรองรับคำสั่ง json_encode() ซึ่งปกติจะกำหนดเป็นตัวแปร array ดูตัวอย่างด้านล่าง
 
$client->post('/users', ['json' => ['foo' => 'bar']]);
 
    การใช้งาน option นี้ฟังก์ชั่น json_encode() จะถูกเรียกใช้งานอัตโนมัติ ดังนั้น เราจะไม่สามารถปรับ
อะไรเกี่ยวกับการใช้งานฟังก์ชั่นนี้ได้ หากต้องการปรับใช้งานฟังก์ชั่น json_encode() แบบกำหนดเองได้
ให้เราเปลี่ยนไปส่งข้อมูลโดยใช้รูปแบบคำสั่ง setBody() และ setHeader() แทน
 
 
    multipart
    ใช้สำหรับส่งข้อมูลไปยัง API ที่รองรับการส่งไฟล์ ส่วนของค่า Content-Type header จะเป็น 
multipart/form-data โดยในขั้นตอนการกำหนดไฟล์ที่จะส่ง เราต้องใช้งานร่วมกับ CURLFile class 
ดูตัวอย่างการกำหนด option 
 
$client->post('/users', [
        'multipart' => [
                'name' => 'demo',
                'email' => 'demo@example.com',
                'userfile' => new \CURLFile('/path/to/file.txt')
        ]
]);
 
 
    query
    ใช้สำหรับกำหนด query string ที่ต้องการเพิ่มไปใน Request URL เราสามารถกำหนด query option
ในรูปแบบตัวแปร array ดูตัวอย่างประกอบ
 
// จะเรียกไปยัง /users?foo=bar
$client->get('/users', ['query' => ['foo' => 'bar']]);
// จะเรียกไปยัง /users?foo=bar&waa=yoo
$client->get('/users', ['query' => ['foo' => 'bar','waa' => 'yoo',]]);
 
 
    timeout
    ใช้สำหรับกำหนดเวลาสิ้นสุดการ request โดยปกติแล้ว เมื่อทำการ request จะไม่มีการจำกัดเวลา
การทำงาน แต่ถ้าเราต้องการจำกัดเวลาทำงาน สามารถกำหนดค่า วินาที ในกับค่า option นี้ได้
 
// request นี้จะทำงานนานสุดไม่เกิน 5 วินาที หากยังไม่มีข้อมูลกลับมาใน 5 วินาที 
// ก็ให้หยุดการทำงานไป
$client->get('/users', ['timeout' => 5]);
 
 
    verify
    ใช้สำหรับกำหนดการทำงานร่วมกับ HTTPS หากกำหนดค่าเป็น true เราจะต้องทำการ verify SSL 
certificate ด้วย หรือหากไม่ต้องการ verify ให้กำหนดค่าเป็น false ดูตัวอย่างการกำหนด และใช้งาน
 
// ใช้งาน CA bundle ของระบบ (ค่านี้เป็นค่าเริ่มต้น ไม่กำหนดก็ได้ ถ้าใช้ค่านี้)
$client->get('/users', ['verify' => true]);

// ใช้งาน SSL certificate แบบกำหนดเอง
$client->get('/users', ['verify' => '/path/to/cert.pem']);

// ปิดการตรวจสอบความทั้งหมด. (ไม่ปลอดภัย แต่ก็ขึ้นกับการใช้งาน)
$client->get('/users', ['verify' => false]);
 
 
 

    การใช้งาน Response Object

    หลังจากที่เราทำการ request ไปยัง api และได้รับ response object กลับมา เราสามารถจัดการ
คำสั่งต่างๆ ของ response object ผ่านตัวแปร ในรูปแบบดังนี้
 
$options = [
        'baseURI' => 'https://jsonplaceholder.typicode.com'
];
$client = service('curlrequest',$options);
$response = $client->get('/users');
echo $response->getStatusCode(); // 200
echo $response->getBody(); // ข้อมูล JSON String Data
echo $response->getHeader('Content-Type'); // Content-Type:  application/json; charset=utf-8
echo $response->getHeaderLine('Content-Type'); // application/json; charset=utf-8
 
    เนื่องจากตัวแปร $response เป็น instance ของ response object เราสามารถใช้คำสั่งต่างๆ ของ
response object ได้ โดยส่วนใหญ่ข้อมูลที่เราจะใช้จาก API ก็จะเป็นข้อมูลส่วนของคำสั่ง getBody()
และส่วนของสถานะ getStatusCode() เป็นหลัก
 
$code   = $response->getStatusCode();    // 200
$reason = $response->getReason();      // OK
$body = $response->getBody();
 
    กรณีเราได้ข้อมูลเป็น JSON string data และต้องการตรวจสอบความถูกต้องของข้อมูล ก่อนแปลง
มาเป็นข้อมูล array เพื่อใข้งาน สามารถกำหนดในลักษณะนี้ได้
 
$body = $response->getBody();
if (strpos($response->getHeader('content-type'), 'application/json') !== false)
{
        $body = json_decode($body); // แปลง JSON เป็น Array
		print_r($body); // ทดสอบแสดงค่า
}
 
 
    แนวทาง รูปแบบ และวิธีใช้งาน CURLRequest ใน CI4 ข้างต้น หวังว่าจะมีประโยชน์ในการนำไป
ปรับประยุกต์ใช้งานต่อไปได้


กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ







เนื้อหาที่เกี่ยวข้อง






เนื้อหาพิเศษ เฉพาะสำหรับสมาชิก

กรุณาล็อกอิน เพื่ออ่านเนื้อหาบทความ

ยังไม่เป็นสมาชิก

สมาชิกล็อกอิน



( หรือ เข้าใช้งานผ่าน Social Login )




URL สำหรับอ้างอิง











เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ