Categories
Computer Data

การเขียนโค้ดเพื่อใช้งาน GraphQL โดยไม่ใช้ไลบรารี

เวลาที่ส่งข้อมูลระหว่าง Client และ Server ผ่านทางจาวาสคริปโดยเรียกใช้งานผ่านทาง AJAX ปกติ เราจะส่งข้อมูลโดยวิธี POST ผ่านการพิมพ์โค้ดตามด้านล่างนี้ (ในตัวอย่างจะใช้ XMLHttpRequest แต่จะใช้ Fetch, Axios หรืออื่น ๆ ก็ได้ เพราะได้ผลเหมือนกัน)

let ajaxrequest = new XMLHttpRequest();  
ajaxrequest.open("POST", "<url>");  
ajaxrequest.onload = (event) => {      
    if(ajaxrequest.readyState == ajaxrequest.DONE) {             
        if(ajaxrequest.status == 200) {              
        /* Do Something */          
        } else {              
        console.error("[*] Error!);          
        }      
    }  
};  

ajaxrequest.onprogress = (event) => {          
    console.log('Processing...');  
};  

ajaxrequest.send(`argument=value&argument2=value`);

เมื่อใช้งานคำสั่งนี้แล้ว ข้อมูลจะได้รับการส่งไปยัง Server เพื่อประมวลผลต่อ จากนั้นเมื่อประมวลผลสำเร็จแล้ว ทางฝั่ง Server จะส่งข้อมูลกลับมาทาง Client เพื่อนำไปประมวลผลต่อ ขั้นตอนนี้แหละ ที่คนนำไปสร้าง API ที่ใช้กันอยู่ในปัจจุบันนี้ที่มีชื่อว่า REST API

REST API

REST API (ย่อมาจาก Representational State Transfer API) เป็นรูปแบบการส่งข้อมูลรูปแบบหนึ่งที่อยู่บนพื้นฐานของ HTTP Protocol เทคนิคนี้อนุญาตให้เราส่งข้อมูลในรูปแบบ JSON (JavaScript Object Notion), Text, File หรืออื่น ๆ แต่ที่ใช้กันบ่อยก็เป็น JSON เนื่องจากสะดวก และรองรับเว็บเบราวเซอร์หลายชนิด แถมเทคนิคนี้ใช้งานได้ง่าย ใช้ทำ Web Service ที่เกี่ยวข้องกับ CRUD ได้เลย เนื่องจากเราใช้งานโค้ดตามข้างบนได้เพียงแต่เปลี่ยนวิธีการส่งข้อมูลผ่านทาง HTTP Protocol ตามตัวอย่างด้านล่างนี้

  • GET — R(etrieve) เรียกดูข้อมูล
  • POST — C(reate) เพิ่มข้อมูล
  • PUT — U(pdate) แก้ไขข้อมูล
  • DELETE — D(elete) ลบข้อมูล

อย่างไรก็ดี เราไม่จำเป็นต้องใช้งานตามข้างบนนี้เป๊ะ ๆ ก็ได้ ใช้งานแค่ POST กับ GET ก็ยังใช้งานได้ตามปกติ เพียงแต่ขึ้นกับทีมที่เขียนโปรแกรมว่าตกลงยังไงนี่แหละครับ

ต่อมา เราจะมาพูดถึง GraphQL

GraphQL

REST API เป็นไลบรารีที่นิยมสำหรับการสร้าง Web Service อย่างไรก็ดีการใช้งาน REST API ก็มีข้อเสียหลัก ๆ ก็ต้องส่งข้อมูลผ่านทาง HTTP Protocol หลายรอบ (Multiple requests) และรับข้อมูลที่มากเกินจำเป็น (Over-fetching)

ดังนั้นแล้ว GraphQL จึงได้รับการพัฒนาขึ้นเพื่อแก้ปัญหาตามย่อหน้าด้านบนนี้ แล้วมันคืออะไร?

GraphQL เป็นโค้ดภาษาหนึ่งที่ใช้เรียกงาน API ผ่านทาง HTTP Protocol รูปแบบหนึ่งเพื่อจัดการข้อมูลได้ตามที่ต้องการ เครื่องมือนี้ได้รับการพัฒนาโดยบริษัท Meta (Facebook เดิม) ตั้งแต่ปี 2012 และเทคนิคนี้ได้รับการนำไปใช้งานจริงในหลายเว็บไซต์ ได้แก่ Github, Pinterest, Coursera เป็นต้น

การใช้งาน ใช้งานได้ไม่ยากผ่านทางไลบรารีที่นิยมอย่างตัว GraphQL เอง หรือใช้งานผ่านไลบรารี Apollo Server/Client ก็ได้ อย่างไรก็ดี ในบทความนี้จะไม่ลงลึกเรื่องไลบรารี เราจะมาพูดถึงการส่งข้อมูล GraphQL ที่ไม่ได้ใช้งานไลบรารีกันดีกว่า

การส่งข้อมูลผ่านทาง GraphQL ที่ใช้งานบ่อยก็เป็นการเรียกข้อมูล และการจัดการข้อมูลผ่านทางการใช้คำสั่งที่เกี่ยวข้องกับ query และ mutation

query

query เป็นการเรียกใช้ฟังก์ชันเพื่อดึงข้อมูลจากฐานข้อมูล สำหรับการแสดงผล และประมวลผลบน Client ในขั้นตอนต่อไป เราเขียน Schema สำหรับการเรียกข้อมูลบนเซิร์ฟเวอร์ได้ตามตัวอย่างด้านล่างนี้

{    
    <GraphQL query command> (<GraphQL query arguments>) {         
        <the data that you want to be returned from the server>    
    }  
}

ตัวอย่างการเขียน Schema ก็เขียนตามด้านล่างนี้ครับ

let str_query = `{    
    getUser(user_id: "${ user_id }") {        
        name        
        surname    
    }  
}`;

เมื่อเขียน Schema เสร็จแล้ว เราเขียน Argument สำหรับการนำไปใช้งานผ่าน XMLHttpRequest ได้ตามด้านล่างนี้

  let query = { query: str_query};

เมื่อเขียน Argument เสร็จแล้ว เราก็ต้องส่งข้อมูลจาก Client ไปยัง Server เราส่งข้อมูลผ่าน XMLHttpRequest ได้ตามด้านล่างนี้

  let ajaxrequest = new XMLHttpRequest();
    
  ajaxrequest.responseType = 'json';
  ajaxrequest.open("POST", "<URL for GraphQL Server>");
  ajaxrequest.setRequestHeader('Content-Type', 'application/json');
  ajaxrequest.onload = function () {
      if(ajaxrequest.status == 200) {
          /* Do Something */
      } else if(ajaxrequest.status >= 400 && ajaxrequest.status < 500) {
          /* Do Something for Client Error */
      } else if(ajaxrequest.status >= 500 && ajaxrequest.status < 600) {
          /* Do Something for Internal Server Error */
      }
  };

  ajaxrequest.send(JSON.stringify(query));

จากนั้น เมื่อเรียกใช้งานคำสั่งตามด้านบนนี้ ข้อมูลที่เขียนในรูปแบบ GraphQL จะส่งจาก Client ไปยัง Server แล้วทางนั้นจะคืนข้อมูล name, surname ที่อยู่ในรูปแบบ JSON ได้ตามที่ต้องการครับ

mutation

mutation เป็นการเรียกใช้ฟังก์ชันเพื่อเปลี่ยนแปลงข้อมูล แล้วแสดงผลข้อมูลกลับมาที่เราต้องการ เราเขียน Schema ของ mutation ได้ตามตัวอย่างด้านล่างนี้ครับ

  let query = `mutation {
    <GraphQL Mutation Command>(<Arguments>) {
      <the data that you want to be returned from the server>
    }
  }`;

ต่อมา เรานำ Argument ที่เขียนแล้วส่งข้อมูลผ่านทาง XMLHttpRequest ได้ด้วยการเขียนโค้ดตามตัวอย่างด้านล่างนี้

  let ajaxrequest = new XMLHttpRequest();
  let form_data = new FormData();
  let map = {};

  ajaxrequest.responseType = 'json';
  ajaxrequest.open("POST", "<GraphQL server URL>");
  ajaxrequest.onload = function () {
      if(ajaxrequest.status == 200) {
          /* Do Something */
      } else if(ajaxrequest.status >= 400 && ajaxrequest.status < 500) {
          /* Do Something for Client Error */
      } else if(ajaxrequest.status >= 500 && ajaxrequest.status < 600) {
          /* Do Something for Internal Server Error */
      }
  };

  // FormData
  form_data.append("operations", JSON.stringify({ query }));
  form_data.append("map", JSON.stringify(map));

  // Send Form Data
  ajaxrequest.send(form_data);

สำหรับการอัพโหลดไฟล์ เราพิมพ์ Schema เพื่ออัพโหลดไฟล์ได้ตามด้านล่างนี้

  let query = `mutation($file: Upload!) {      <GraphQL Upload   let query = `mutation($file: Upload!) {
      <GraphQL Upload mutation command>(<Arguments>, upload_file: $file) {
          <the data that you want to be returned from the server>
      }
  }`;
  let variables = { "file": null };
  let map = { "0": ["variables.file"] };

แล้วสร้างตัวแปรเพื่อรองรับ File Object สำหรับการอัพโหลดไฟล์ตามโค้ดด้านล่าง ในตัวอยา่งจะใช้ File Input ครับ


let fileObj = document.getElementById('<File Input ID>').files[0];

ต่อมา เราเรียกใช้งาน XMLHttpRequest เจ้าเดิมได้โดยการพิมพ์คำสั่งตามตัวอย่างด้านล่างนี้

  let ajaxrequest = new XMLHttpRequest();    
  let ajaxrequest = new XMLHttpRequest();
  ajaxrequest.responseType = 'json';
  ajaxrequest.open('POST', graphql_url);
  ajaxrequest.onload = function () {
      if(ajaxrequest.status == 200) {
          /* Do Something */
      } else if(ajaxrequest.status >= 400 && ajaxrequest.status < 500) {
          /* Do Something for Client Error */
      } else if(ajaxrequest.status >= 500 && ajaxrequest.status < 600) {
          /* Do Something for Internal Server Error */
      }
  };
  
	// FormData
	form_data.append("operations", JSON.stringify({ query, variables }));
	form_data.append("map", JSON.stringify(map));
	form_data.append("0", fileObj);

	// Send Form Data
  ajaxrequest.send(form_data);

เมื่อเรียกใช้งานจะพบว่าไฟล์ได้รับการอัพโหลดเรียบร้อย

เมื่อเราเขียนโค้ดตามด้านบนแล้ว สามารถทดสอบบนเว็บเบราวเซอร์ได้เลย ผลลัพธ์ก็จะเหมือนการใช้งาน GraphQL ผ่านทางไลบรารี อย่างไรก็ดี การใช้งานตามที่เขียนนี้จะดูยุ่งยากกว่าการใช้งานผ่านทางไลบรารีครับ ดังนั้นแล้วถ้าใช้งานไลบรารีได้ ก็แนะนำให้ใช้ไลบรารีได้ก่อนได้เลย โดยไลบรารีที่เราเคยใช้ก็ตัวอย่างเช่น Apollo Client ครับ

By Kittisak Chotikkakamthorn

อดีตนักศึกษาฝึกงานทางด้าน AI ที่ภาควิชาวิศวกรรมไฟฟ้า มหาวิทยาลัย National Chung Cheng ที่ไต้หวัน ที่กำลังหางานทางด้าน Data Engineer ที่มีความสนใจทางด้าน Data, Coding และ Blogging / ติดต่อได้ที่: contact [at] nickuntitled.com

Exit mobile version