เว็บไซต์ที่ขับเคลื่อนด้วย API ของฉันช่วยให้ฉันเดินทางไปทั่วโลกได้อย่างไร
เผยแพร่แล้ว: 2022-03-10(นี่คือโพสต์ที่ได้รับการสนับสนุน) เมื่อเร็ว ๆ นี้ ฉันตัดสินใจสร้างเว็บไซต์ส่วนตัวของฉันขึ้นมาใหม่ เพราะมันอายุหกขวบและดู - พูดอย่างสุภาพ - ค่อนข้าง "ล้าสมัย" เป้าหมายคือการรวมข้อมูลบางอย่างเกี่ยวกับตัวฉัน พื้นที่บล็อก รายชื่อโครงการด้านล่าสุดของฉัน และกิจกรรมที่จะเกิดขึ้น
ขณะที่ฉันทำงานของลูกค้าเป็นครั้งคราว มีสิ่งหนึ่งที่ฉันไม่ต้องการจัดการ - ฐานข้อมูล ! ก่อนหน้านี้ ฉันสร้างไซต์ WordPress สำหรับทุกคนที่ต้องการ ส่วนการเขียนโปรแกรมมักจะสนุกสำหรับฉัน แต่การเผยแพร่ การย้ายฐานข้อมูลไปยังสภาพแวดล้อมที่แตกต่างกัน และการเผยแพร่จริงนั้นน่ารำคาญอยู่เสมอ ผู้ให้บริการโฮสติ้งราคาถูกเสนอเฉพาะเว็บอินเตอร์เฟสที่ไม่ดีในการตั้งค่าฐานข้อมูล MySQL และการเข้าถึง FTP เพื่ออัพโหลดไฟล์เป็นส่วนที่แย่ที่สุด ฉันไม่ต้องการจัดการกับสิ่งนี้สำหรับเว็บไซต์ส่วนตัวของฉัน
ดังนั้นข้อกำหนดที่ฉันมีสำหรับการออกแบบใหม่คือ:
- สแต็คเทคโนโลยีที่ทันสมัยโดยอิงจาก JavaScript และเทคโนโลยีฟรอนท์เอนด์
- โซลูชันการจัดการเนื้อหาเพื่อแก้ไขเนื้อหาได้จากทุกที่
- ไซต์ที่มีประสิทธิภาพดีพร้อมผลลัพธ์ที่รวดเร็ว
ในบทความนี้ ฉันต้องการแสดงให้คุณเห็นว่าฉันสร้างอะไร และเว็บไซต์ของฉันกลายเป็นเพื่อนประจำวันของฉันได้อย่างไร
การกำหนดรูปแบบเนื้อหา
การเผยแพร่สิ่งต่าง ๆ บนเว็บดูเหมือนจะง่าย เลือกระบบจัดการเนื้อหา ( CMS ) ที่มีโปรแกรม แก้ไข แบบ WYSIWYG ( ใช้งาน ไม่ ได้ ใช้งานไม่ได้ ) สำหรับทุกหน้าที่ต้องการ และ บรรณาธิการ ทั้งหมดสามารถจัดการเนื้อหาได้อย่างง่ายดาย แค่นั้นเองเหรอ?
หลังจากสร้างเว็บไซต์ลูกค้าหลายแห่ง ตั้งแต่ร้านกาแฟเล็กๆ ไปจนถึงบริษัทสตาร์ทอัพที่กำลังเติบโต ฉันก็พบว่าโปรแกรมแก้ไข WYSIWYG ศักดิ์สิทธิ์นั้นไม่ใช่สัญลักษณ์แสดงหัวข้อย่อยสีเงินที่เราทุกคนกำลังมองหาอยู่เสมอไป อินเทอร์เฟซเหล่านี้มีจุดมุ่งหมายเพื่อทำให้การสร้างเว็บไซต์เป็นเรื่องง่าย แต่ประเด็นสำคัญคือ:
การสร้างเว็บไซต์ไม่ใช่เรื่องง่าย
ในการสร้างและแก้ไขเนื้อหาของเว็บไซต์โดยไม่ทำลายมันอย่างต่อเนื่อง คุณต้องมีความรู้เชิงลึกเกี่ยวกับ HTML และอย่างน้อยต้องเข้าใจ CSS เล็กน้อย นั่นไม่ใช่สิ่งที่คุณคาดหวังได้จากบรรณาธิการของคุณ
ฉันเคยเห็นเลย์เอาต์ที่ซับซ้อนที่น่ากลัวซึ่งสร้างขึ้นด้วยโปรแกรมแก้ไขแบบ WYSIWYG และฉันไม่สามารถตั้งชื่อสถานการณ์ทั้งหมดเมื่อทุกอย่างพังทลายเพราะระบบเปราะบางเกินไป สถานการณ์เหล่านี้นำไปสู่การต่อสู้และความรู้สึกไม่สบายที่ทุกฝ่ายต่างกล่าวโทษซึ่งกันและกันในสิ่งที่หลีกเลี่ยงไม่ได้ ฉันพยายามหลีกเลี่ยงสถานการณ์เหล่านี้อยู่เสมอ และสร้างสภาพแวดล้อมที่สะดวกสบายและมั่นคงสำหรับบรรณาธิการ เพื่อหลีกเลี่ยงอีเมลที่โกรธจัดว่า "ช่วยด้วย! ทุกอย่างพังทลาย”
เนื้อหาที่มีโครงสร้างช่วยแก้ปัญหาให้คุณได้
ฉันเรียนรู้ค่อนข้างเร็วว่าผู้คนไม่ค่อยทำของแตกเมื่อฉันแยกเนื้อหาเว็บไซต์ที่จำเป็นทั้งหมดออกเป็นหลายๆ ส่วน แต่ละส่วนเกี่ยวข้องกันโดยไม่ต้องนึกถึงการเป็นตัวแทนใดๆ ใน WordPress สามารถทำได้โดยใช้ประเภทโพสต์ที่กำหนดเอง โพสต์ที่กำหนดเองแต่ละประเภทสามารถมีคุณสมบัติหลายอย่างพร้อมช่องข้อความที่เข้าใจง่าย ฉันฝังแนวคิดของการ คิดไว้ในหน้ากระดาษ อย่างสมบูรณ์
งานของฉันคือเชื่อมต่อส่วนต่างๆ ของเนื้อหาและสร้างหน้าเว็บจากบล็อกเนื้อหาเหล่านี้ ซึ่งหมายความว่าบรรณาธิการสามารถทำได้เพียงเล็กน้อยเท่านั้น หากมี การเปลี่ยนแปลงภาพบนเว็บไซต์ของพวกเขา พวกเขารับผิดชอบเนื้อหาและเนื้อหาเท่านั้น ฉันจำเป็นต้องทำการเปลี่ยนแปลงด้านภาพ — ไม่ใช่ทุกคนที่สามารถจัดรูปแบบไซต์ได้ และเราสามารถหลีกเลี่ยงสภาพแวดล้อมที่เปราะบางได้ แนวคิดนี้ให้ความรู้สึกเหมือนเป็นการประนีประนอมอย่างมากและมักจะได้รับการตอบรับเป็นอย่างดี
ต่อมา ฉันค้นพบว่าสิ่งที่ฉันทำคือ การกำหนดรูปแบบเนื้อหา Rachel Lovinger ให้คำจำกัดความในบทความที่ยอดเยี่ยมของเธอเรื่อง “Content Modelling: A Master Skill” รูปแบบเนื้อหาดังต่อไปนี้:
“โมเดลเนื้อหาจะบันทึกเนื้อหาประเภทต่าง ๆ ทั้งหมดที่คุณจะมีสำหรับโปรเจ็กต์ที่กำหนด มันมีคำจำกัดความโดยละเอียดขององค์ประกอบของเนื้อหาแต่ละประเภทและความสัมพันธ์ซึ่งกันและกัน”
เริ่มต้นด้วยการสร้างแบบจำลองเนื้อหาทำงานได้ดีสำหรับลูกค้าส่วนใหญ่ ยกเว้นลูกค้ารายเดียว
“สเตฟาน ฉันไม่ได้กำหนดสคีมาฐานข้อมูลของคุณ!”
แนวคิดของโครงการเดียวนี้คือการสร้างเว็บไซต์ขนาดใหญ่ที่ควรสร้างการเข้าชมแบบออร์แกนิกจำนวนมากโดยการจัดหาเนื้อหาจำนวนมาก — ในรูปแบบทั้งหมดที่แสดงในหน้าและสถานที่ต่างๆ ฉันจัดการประชุมเพื่อหารือเกี่ยวกับกลยุทธ์ของเราในการเข้าถึงโครงการนี้
ฉันต้องการกำหนดหน้าและรูปแบบเนื้อหาทั้งหมดที่ควรรวมไว้ ไม่สำคัญหรอกว่าวิดเจ็ตเล็กๆ ใดหรือแถบด้านข้างที่ลูกค้ามีอยู่ในใจ ฉันต้องการให้มันชัดเจน เป้าหมายของฉันคือการสร้างโครงสร้างเนื้อหาที่มั่นคง ซึ่งทำให้สามารถจัดเตรียมอินเทอร์เฟซที่ใช้งานง่ายสำหรับบรรณาธิการ และให้ข้อมูลที่นำกลับมาใช้ใหม่ได้เพื่อแสดงในรูปแบบที่คิดได้
ปรากฏว่า แนวคิดของโครงการนี้ไม่ชัดเจนนัก และฉันไม่สามารถหาคำตอบสำหรับคำถามทั้งหมดของฉันได้ หัวหน้าโครงการไม่เข้าใจว่าเราควรจะเริ่มต้นด้วยการสร้างแบบจำลองเนื้อหาที่เหมาะสม (ไม่ใช่การออกแบบและพัฒนา) สำหรับเขา นี่เป็นเพียงหน้ากระดาษมากมาย เนื้อหาที่ซ้ำกันและพื้นที่ข้อความขนาดใหญ่เพื่อเพิ่มข้อความจำนวนมาก ดูเหมือนจะไม่มีปัญหา ในใจของเขา คำถามที่ฉันมีเกี่ยวกับโครงสร้างเป็นคำถามทางเทคนิค และไม่ควรต้องกังวลกับคำถามเหล่านั้น ฉันไม่ได้ทำโปรเจ็กต์
สิ่งสำคัญคือ การสร้างแบบจำลองเนื้อหาไม่เกี่ยวกับฐานข้อมูล
มันเกี่ยวกับการทำให้เนื้อหาของคุณสามารถเข้าถึงได้และพิสูจน์ได้ในอนาคต หากคุณไม่ได้กำหนดความต้องการเนื้อหาของคุณในช่วงเริ่มต้นของโครงการ จะเป็นการยากมาก หากไม่สามารถทำได้ การนำกลับมาใช้ใหม่ในภายหลัง
การสร้างแบบจำลองเนื้อหาที่เหมาะสมเป็นกุญแจสำคัญสำหรับเว็บไซต์ปัจจุบันและในอนาคต
เนื้อหา: CMS หัวขาด
เห็นได้ชัดว่าฉันต้องการติดตามการสร้างแบบจำลองเนื้อหาที่ดีสำหรับไซต์ของฉันด้วย อย่างไรก็ตาม มีอีกสิ่งหนึ่ง ฉันไม่ต้องการจัดการกับชั้นการจัดเก็บเพื่อสร้างเว็บไซต์ใหม่ของฉัน ดังนั้นฉันจึงตัดสินใจใช้ Contentful ซึ่งเป็น CMS ที่ไม่มีส่วนหัว ซึ่งฉันกำลังดำเนินการอยู่ (ข้อจำกัดความรับผิดชอบแบบเต็ม!) “หัวขาด” หมายความว่าบริการนี้มีเว็บอินเตอร์เฟสเพื่อจัดการเนื้อหาในระบบคลาวด์และมี API ที่จะให้ข้อมูลของฉันกลับมาในรูปแบบ JSON การเลือก CMS นี้ช่วยให้ฉันทำงานได้อย่างมีประสิทธิภาพในทันที เนื่องจากฉันมี API ที่พร้อมใช้งานภายในไม่กี่นาที และฉันไม่ต้องจัดการกับการตั้งค่าโครงสร้างพื้นฐานใดๆ Contentful ยังมีแผนฟรีซึ่งเหมาะสำหรับโครงการขนาดเล็ก เช่น เว็บไซต์ส่วนตัวของฉัน
ตัวอย่างแบบสอบถามเพื่อรับโพสต์บล็อกทั้งหมดมีลักษณะดังนี้:
<a href="https://cdn.contentful.com/spaces/space_id/entries?access_token=access_token&content_type=post">https://cdn.contentful.com/spaces/space_id/entries?access_token=access_token&content_type=post</a>
และคำตอบในเวอร์ชันย่อจะมีลักษณะดังนี้:
{ "sys": { "type": "Array" }, "total": 7, "skip": 0, "limit": 100, "items": [ { "sys": { "space": {...}, "id": "455OEfg1KUskygWUiKwmkc", "type": "Entry", "createdAt": "2016-07-29T11:53:52.596Z", "updatedAt": "2016-11-09T21:07:19.118Z", "revision": 12, "contentType": {...}, "locale": "en-US" }, "fields": { "title": "How to React to Changing Environments Using matchMedia", "excerpt": "...", "slug": "how-to-react-to-changing-environments-using-match-media", "author": [...], "body": "...", "date": "2014-12-26T00:00+02:00", "comments": true, "externalUrl": "https://4waisenkinder.de/blog/2014/12/26/handle-environment-changes-via-window-dot-matchmedia/" }, {...}, {...}, {...}, {...}, {...}, {...} ] } }
ส่วนที่ยอดเยี่ยมเกี่ยวกับ Contentful คือการสร้างแบบจำลองเนื้อหาที่ยอดเยี่ยม ซึ่งฉันต้องการ เมื่อใช้เว็บอินเทอร์เฟซที่ให้มา ฉันสามารถกำหนดส่วนเนื้อหาที่จำเป็นทั้งหมดได้อย่างรวดเร็ว คำจำกัดความของโมเดลเนื้อหาเฉพาะใน Contentful เรียกว่าประเภทเนื้อหา สิ่งที่ควรชี้ให้เห็นในที่นี้คือความสามารถในการจำลองความสัมพันธ์ระหว่างรายการเนื้อหา ตัวอย่างเช่น ฉันสามารถเชื่อมต่อผู้เขียนกับโพสต์บนบล็อกได้อย่างง่ายดาย ซึ่งอาจส่งผลให้โครงสร้างข้อมูลมีโครงสร้าง ซึ่งเหมาะอย่างยิ่งสำหรับการนำกลับมาใช้ใหม่ในกรณีการใช้งานต่างๆ
ดังนั้นฉันจึงตั้งค่าโมเดลเนื้อหาของฉันโดยไม่ต้องนึกถึงหน้าใด ๆ ที่ฉันอาจต้องการสร้างในอนาคต
ขั้นตอนต่อไปคือการหาว่าฉันต้องการทำอะไรกับข้อมูลนี้ ฉันถามนักออกแบบที่ฉันรู้จัก และเขาก็สร้างหน้าดัชนีของเว็บไซต์ที่มีโครงสร้างดังต่อไปนี้
การแสดงผลหน้า HTML โดยใช้ Node.js
ตอนนี้มาถึงส่วนที่ยุ่งยาก จนถึงตอนนี้ ฉันไม่ต้องจัดการกับที่เก็บข้อมูลและฐานข้อมูล ซึ่งเป็นความสำเร็จที่ยอดเยี่ยมสำหรับฉัน ฉันจะสร้างเว็บไซต์ได้อย่างไรในเมื่อมีเพียง API ที่พร้อมใช้งาน
แนวทางแรกของฉันคือแนวทางที่ต้องทำด้วยตัวเอง ฉันเริ่มเขียนสคริปต์ Node.js ง่ายๆ ซึ่งจะดึงข้อมูลและแสดง HTML บางส่วนออกมา
การแสดงผลไฟล์ HTML ล่วงหน้าเป็นไปตามข้อกำหนดหลักข้อใดข้อหนึ่งของฉัน HTML แบบคงที่สามารถให้บริการได้เร็วมาก
มาดูสคริปต์ที่ฉันใช้กัน
'use strict'; const contentful = require('contentful'); const template = require('lodash.template'); const fs = require('fs'); // create contentful client with particular credentials const client = contentful.createClient({ space: 'your_space_id', accessToken: 'your_token' }); // cache templates to not read // them over and over again const TEMPLATES = { index : template(fs.readFileSync(`${__dirname}/templates/index.html`)) }; // fetch all the data Promise.all([ // get posts client.getEntries({content_type: 'content_type_post_id'}), // get events client.getEntries({content_type: 'content_type_event_id'}), // get projects client.getEntries({content_type: 'content_type_project_id'}), // get talk client.getEntries({content_type: 'content_type_talk_id'}), // get specific person client.getEntries({'sys.id': 'person_id'}) ]) .then(([posts, events, projects, talks, persons]) => { const renderedHTML = TEMPLATES.index({ posts, events, projects, talks, person : persons.items[0] }) fs.writeFileSync(`${__dirname}/build/index.html`, renderedHTML); console.log('Rendered HTML'); }) .catch(console.error);
<!doctype html> <html lang="en"> <head> <!-- ... --> </head> <body> <!-- ... --> <h2>Posts</h2> <ul> <% posts.items.forEach( function( talk ) { %> <li><%- talk.fields.title %> <% }) %> </ul> <!-- ... --> </body> </html>
สิ่งนี้ใช้ได้ดี ฉันสามารถสร้างเว็บไซต์ที่ต้องการด้วยวิธีที่ยืดหยุ่นได้อย่างสมบูรณ์ โดยทำการตัดสินใจทั้งหมดเกี่ยวกับโครงสร้างไฟล์และฟังก์ชันการทำงาน การแสดงผลประเภทเพจที่แตกต่างกันด้วยชุดข้อมูลที่แตกต่างกันโดยสิ้นเชิงก็ไม่มีปัญหาอะไร ทุกคนที่ต่อสู้กับกฎและโครงสร้างของ CMS ที่มีอยู่ซึ่งมาพร้อมกับการเรนเดอร์ HTML รู้ดีว่าอิสระอย่างสมบูรณ์นั้นเป็นสิ่งที่ยอดเยี่ยม โดยเฉพาะอย่างยิ่ง เมื่อตัวแบบข้อมูลมีความซับซ้อนมากขึ้นเมื่อเวลาผ่านไป ซึ่งรวมถึงความสัมพันธ์หลายๆ อย่าง ความยืดหยุ่นก็เป็นผลดี
ในสคริปต์ Node.js นี้ ไคลเอ็นต์ Contentful SDK จะถูกสร้างขึ้นและดึงข้อมูลทั้งหมดโดยใช้วิธีการไคลเอ็นต์ getEntries
วิธีการทั้งหมดที่มีให้ของไคลเอ็นต์เป็นไปตามคำสัญญา ซึ่งทำให้ง่ายต่อการหลีกเลี่ยงการเรียกกลับที่ซ้อนกันอย่างลึกซึ้ง สำหรับการสร้างเทมเพลต ฉันตัดสินใจใช้เครื่องมือสร้างเทมเพลตของ lodash สุดท้าย สำหรับการอ่านและเขียนไฟล์ Node.js มีโมดูลเนทีฟ fs
ซึ่งจะใช้ในการอ่านเทมเพลตและเขียน HTML ที่แสดงผล
อย่างไรก็ตาม มีข้อเสียประการหนึ่งสำหรับแนวทางนี้ มันเป็นกระดูกที่เปลือยเปล่ามาก แม้ว่าวิธีนี้จะยืดหยุ่นได้เต็มที่ แต่ก็รู้สึกเหมือนกำลังสร้างวงล้อขึ้นใหม่ สิ่งที่ฉันกำลังสร้างนั้นเป็นเครื่องกำเนิดไซต์แบบคงที่และมีจำนวนมากอยู่แล้ว ถึงเวลาเริ่มต้นใหม่ทั้งหมดอีกครั้ง
ไปหาเครื่องสร้างไซต์แบบคงที่จริง
ตัวสร้างไซต์คงที่ที่มีชื่อเสียง เช่น Jekyll หรือ Middleman มักจะจัดการกับไฟล์ Markdown ซึ่งจะแสดงผลเป็น HTML บรรณาธิการทำงานกับสิ่งเหล่านี้ และเว็บไซต์ถูกสร้างขึ้นโดยใช้คำสั่ง CLI วิธีการนี้ล้มเหลวในข้อกำหนดเบื้องต้นประการหนึ่งของฉัน ฉันต้องการที่จะสามารถแก้ไขไซต์ได้ทุกที่ โดยไม่ต้องอาศัยไฟล์ที่อยู่ในคอมพิวเตอร์ส่วนตัวของฉัน
ความคิดแรกของฉันคือการแสดงไฟล์ Markdown เหล่านี้โดยใช้ API แม้ว่าสิ่งนี้จะได้ผล แต่ก็รู้สึกไม่ถูกต้อง การแสดงผลไฟล์ Markdown เพื่อแปลงเป็น HTML ในภายหลังยังคงเป็นสองขั้นตอนที่ไม่ได้ให้ประโยชน์มากนักเมื่อเทียบกับโซลูชันเริ่มต้นของฉัน
โชคดีที่มีการผสานรวม Contentful เช่น Metalsmith และ Middleman ฉันตัดสินใจเลือก Metalsmith สำหรับโปรเจ็กต์นี้ เนื่องจากมันถูกเขียนใน Node.js และฉันไม่ต้องการนำการพึ่งพา Ruby มาใช้
Metalsmith แปลงไฟล์จากโฟลเดอร์ต้นทางและแสดงผลในโฟลเดอร์ปลายทาง ไฟล์เหล่านี้ไม่จำเป็นต้องเป็นไฟล์ Markdown คุณยังสามารถใช้เพื่อ transpiling Sass หรือปรับภาพของคุณให้เหมาะสม ไม่มีข้อจำกัด และมีความยืดหยุ่นสูง
เมื่อใช้การผสานรวมเนื้อหา ฉันสามารถกำหนดไฟล์ต้นทางบางไฟล์ซึ่งถูกนำไปใช้เป็นไฟล์การกำหนดค่า และสามารถดึงข้อมูลทุกอย่างที่จำเป็นจาก API ได้
--- title: Blog contentful: content_type: content_type_id entry_filename_pattern: ${ fields.slug } entry_template: article.html order: '-fields.date' filter: include: 5 layout: blog.html description: >- Recent articles by Stefan Judis. ---
การกำหนดค่าตัวอย่างนี้แสดงพื้นที่โพสต์บล็อกด้วยไฟล์หลัก blog.html
รวมถึงการตอบกลับคำขอ API แต่ยังแสดงหน้าย่อยหลายหน้าโดยใช้เทมเพลต article.html
ชื่อไฟล์สำหรับเพจย่อยถูกกำหนดผ่าน entry_filename_pattern
อย่างที่คุณเห็น ด้วยสิ่งนี้ ฉันสามารถสร้างเพจของฉันได้อย่างง่ายดาย การตั้งค่านี้ทำงานได้อย่างสมบูรณ์เพื่อให้แน่ใจว่าหน้าทั้งหมดขึ้นอยู่กับ API
เชื่อมต่อบริการกับโครงการของคุณ
ส่วนที่ขาดหายไปเพียงอย่างเดียวคือการเชื่อมต่อไซต์กับบริการ CMS และเพื่อให้แสดงผลใหม่เมื่อมีการแก้ไขเนื้อหา วิธีแก้ปัญหาสำหรับปัญหานี้ — เว็บฮุค ซึ่งคุณอาจคุ้นเคยอยู่แล้วหากคุณใช้บริการเช่น GitHub
Webhooks เป็นคำขอที่จัดทำโดยซอฟต์แวร์เพื่อให้บริการไปยังปลายทางที่กำหนดไว้ก่อนหน้านี้ ซึ่งจะแจ้งให้คุณทราบว่ามีบางอย่างเกิดขึ้น ตัวอย่างเช่น GitHub สามารถ ping คุณกลับเมื่อมีคนเปิดคำขอดึงใน repos ของคุณ เกี่ยวกับการจัดการเนื้อหา เราสามารถใช้หลักการเดียวกันนี้ได้ที่นี่ เมื่อใดก็ตามที่มีบางสิ่งเกิดขึ้นกับเนื้อหา ให้ทำการ ping จุดปลายและทำให้สภาพแวดล้อมเฉพาะตอบสนองต่อสิ่งนั้น ในกรณีของเรา นี่หมายถึงการแสดง HTML ใหม่โดยใช้ metalsmith
เพื่อยอมรับเว็บฮุค ฉันยังใช้โซลูชันจาวาสคริปต์ด้วย ผู้ให้บริการโฮสต์ที่ฉันเลือก (Uberspace) ทำให้สามารถติดตั้ง Node.js และใช้ JavaScript ที่ฝั่งเซิร์ฟเวอร์ได้
const http = require('http'); const exec = require('child_process').exec; const server = http.createServer((req, res) => { res.setHeader('Content-Type', 'text/plain'); // check for secret header // to not open up this endpoint for everybody if (req.headers.secret === 'YOUR_SECRET') { res.end('ok'); // wait for the CDN to // invalidate the data setTimeout(() => { // execute command exec('npm start', { cwd: __dirname }, (error) => { if (error) { return console.log(error); } console.log('Rebuilt success'); }); }, 1000 * 120 ); } else { res.end('Not allowed'); } }); console.log('Started server at 8000'); server.listen(8000);
สคริปต์นี้เริ่มต้นเซิร์ฟเวอร์ HTTP อย่างง่ายบนพอร์ต 8000 โดยจะตรวจสอบคำขอขาเข้าสำหรับส่วนหัวที่ถูกต้องเพื่อให้แน่ใจว่าเป็นเว็บฮุคจากเนื้อหา หากคำขอได้รับการยืนยันเป็นเว็บฮุค คำสั่งที่กำหนดไว้ล่วงหน้า npm start
จะถูกดำเนินการเพื่อแสดงผลหน้า HTML ทั้งหมดอีกครั้ง คุณอาจสงสัยว่าเหตุใดจึงมีการหมดเวลา การดำเนินการนี้จำเป็นต้องหยุดชั่วคราวจนกว่าข้อมูลในระบบคลาวด์จะถูกยกเลิกเนื่องจากข้อมูลที่เก็บไว้จะได้รับบริการจาก CDN
ขึ้นอยู่กับสภาพแวดล้อมของคุณ เซิร์ฟเวอร์ HTTP นี้อาจเข้าถึงอินเทอร์เน็ตไม่ได้ ไซต์ของฉันให้บริการโดยใช้เซิร์ฟเวอร์ apache ดังนั้นฉันจึงจำเป็นต้องเพิ่มกฎการเขียนซ้ำภายในเพื่อให้เซิร์ฟเวอร์โหนดที่ทำงานอยู่สามารถเข้าถึงได้ทางอินเทอร์เน็ต
# add node endpoint to enable webhooks RewriteRule ^rerender/(.*) https://localhost:8000/$1 [P]
ข้อมูล API แรกและมีโครงสร้าง: เพื่อนที่ดีที่สุดตลอดกาล
ณ จุดนี้ ฉันสามารถจัดการข้อมูลทั้งหมดของฉันในระบบคลาวด์ และเว็บไซต์ของฉันจะตอบสนองตามนั้นหลังจากการเปลี่ยนแปลง
ซ้ำไปซ้ำมา
การอยู่บนท้องถนนเป็นส่วนสำคัญในชีวิตของฉัน ดังนั้นจึงจำเป็นต้องมีข้อมูล เช่น ตำแหน่งของสถานที่ที่กำหนดหรือโรงแรมที่ฉันจองไว้เพียงปลายนิ้วสัมผัส โดยปกติแล้วจะจัดเก็บไว้ใน Google สเปรดชีต ตอนนี้ ข้อมูลกระจายไปทั่วสเปรดชีต อีเมลหลายฉบับ ปฏิทินของฉัน และบนเว็บไซต์ของฉัน
ฉันต้องยอมรับว่าฉันสร้างข้อมูลซ้ำซ้อนในโฟลว์ประจำวันของฉัน
ช่วงเวลาของข้อมูลที่มีโครงสร้าง
ฉันฝันถึงแหล่งที่มาของความจริงเพียงแหล่งเดียว (ควรใช้โทรศัพท์ของฉัน) เพื่อดูว่าเหตุการณ์ใดกำลังจะเกิดขึ้นอย่างรวดเร็ว แต่ยังได้รับข้อมูลเพิ่มเติมเกี่ยวกับโรงแรมและสถานที่ต่างๆ ด้วย เหตุการณ์ที่แสดงบนเว็บไซต์ของฉันไม่มีข้อมูลทั้งหมด ณ จุดนี้ แต่เป็นเรื่องง่ายมากที่จะเพิ่มฟิลด์ใหม่ให้กับประเภทเนื้อหาใน Contentful ดังนั้นฉันจึงเพิ่มฟิลด์ที่จำเป็นลงในประเภทเนื้อหา "กิจกรรม"
การใส่ข้อมูลนี้ลงในเว็บไซต์ CMS ของฉันไม่ใช่ความตั้งใจของฉัน เนื่องจากไม่ควรแสดงข้อมูลทางออนไลน์ แต่เมื่อสามารถเข้าถึงได้ผ่าน API ทำให้ฉันตระหนักว่าตอนนี้ฉันสามารถทำสิ่งที่แตกต่างไปจากเดิมอย่างสิ้นเชิงกับข้อมูลนี้ได้
การสร้างแอพเนทีฟด้วย JavaScript
การสร้างแอพสำหรับมือถือเป็นหัวข้อมานานหลายปีแล้ว และมีหลายแนวทางในเรื่องนี้ Progressive Web Apps (PWA) เป็นประเด็นร้อนโดยเฉพาะในทุกวันนี้ การใช้ Service Workers และ Web App Manifest สามารถสร้างประสบการณ์ที่เหมือนแอปได้อย่างสมบูรณ์ตั้งแต่ไอคอนหน้าจอหลักไปจนถึงพฤติกรรมออฟไลน์ที่มีการจัดการโดยใช้เทคโนโลยีเว็บ
มีข้อเสียอย่างหนึ่งที่ต้องพูดถึง Progressive Web Apps กำลังเพิ่มขึ้น แต่ก็ยังไม่หมด ตัวอย่างเช่น พนักงานบริการไม่ได้รับการสนับสนุนบน Safari ในปัจจุบัน และเพียง "อยู่ระหว่างการพิจารณา" จากฝ่าย Apple เท่านั้น นี่เป็นตัวทำลายข้อตกลงสำหรับฉันเนื่องจากฉันต้องการมีแอพที่สามารถใช้งานออฟไลน์บน iPhone ได้เช่นกัน
ดังนั้นฉันจึงมองหาทางเลือกอื่น เพื่อนของฉันคนหนึ่งชอบ NativeScript และคอยบอกฉันเกี่ยวกับเทคโนโลยีที่ค่อนข้างใหม่นี้ NativeScript เป็นเฟรมเวิร์กโอเพนซอร์สสำหรับการสร้างแอปบนอุปกรณ์เคลื่อนที่แบบเนทีฟอย่างแท้จริงด้วย JavaScript ดังนั้นฉันจึงตัดสินใจลองใช้
ทำความรู้จักกับ NativeScript
การตั้งค่า NativeScript ใช้เวลาสักครู่ เนื่องจากคุณต้องติดตั้งหลายสิ่งหลายอย่างเพื่อพัฒนาสำหรับสภาพแวดล้อมแบบเนทีฟโมบายล์ คุณจะได้รับคำแนะนำตลอดขั้นตอนการติดตั้งเมื่อคุณติดตั้งเครื่องมือบรรทัดคำสั่ง NativeScript เป็นครั้งแรกโดยใช้ npm install nativescript -g
จากนั้น คุณสามารถใช้คำสั่งนั่งร้านเพื่อตั้งค่าโครงการใหม่: tns create MyNewApp
อย่างไรก็ตาม นี่ไม่ใช่สิ่งที่ฉันทำ ฉันกำลังสแกนเอกสารและพบตัวอย่างแอปจัดการร้านขายของชำที่สร้างขึ้นใน NativeScript ดังนั้นฉันจึงนำแอปนี้ ขุดลงไปในโค้ด และแก้ไขทีละขั้นตอน เพื่อให้เหมาะสมกับความต้องการของฉัน
ฉันไม่ต้องการที่จะเจาะลึกลงไปในกระบวนการนี้มากเกินไป แต่ในการสร้างรายการที่มีข้อมูลทั้งหมดที่ฉันต้องการนั้น ใช้เวลาไม่นานในการสร้าง
NativeScript เข้ากันได้ดีกับ Angular 2 ซึ่งฉันไม่อยากลองในครั้งนี้เพราะการค้นพบ NativeScript นั้นยิ่งใหญ่พอ ใน NativeScript คุณต้องเขียน "Views" แต่ละมุมมองประกอบด้วยไฟล์ XML ที่กำหนดเค้าโครงพื้นฐานและ JavaScript และ CSS ทางเลือก ทั้งหมดนี้มีการกำหนดไว้ในโฟลเดอร์เดียวต่อการดู
การแสดงรายการอย่างง่ายสามารถทำได้ด้วยเทมเพลต XML ดังนี้:
<!-- call JavaScript function when ready --> <Page loaded="loaded"> <ActionBar title="All Travels" /> <!-- make it scrollable when going too big --> <ScrollView> <!-- iterate over the entries in context --> <ListView items="{{ entries }}"> <ListView.itemTemplate> <Label text="{{ fields.name }}" textWrap="true" class="headline"/> </ListView.itemTemplate> </ListView> </ScrollView> </Page>
สิ่งแรกที่เกิดขึ้นที่นี่คือการกำหนดองค์ประกอบของหน้า ภายในหน้านี้ ฉันได้กำหนด ActionBar
เพื่อให้มีรูปลักษณ์ Android แบบคลาสสิกและพาดหัวข่าวที่เหมาะสม การสร้างสิ่งต่าง ๆ สำหรับสภาพแวดล้อมดั้งเดิมอาจทำได้ยากในบางครั้ง ตัวอย่างเช่น เพื่อให้เกิดการเลื่อนทำงาน คุณต้องใช้ 'ScrollView' สิ่งสุดท้ายคือเพียงแค่วนซ้ำกิจกรรมของฉันโดยใช้ ListView
โดยรวมถือว่าค่อนข้างตรงไปตรงมา!
แต่รายการเหล่านี้มาจากไหนที่ใช้ในมุมมอง ปรากฎว่ามีวัตถุบริบทที่ใช้ร่วมกันที่สามารถใช้สำหรับสิ่งนั้น เมื่ออ่าน XML สำหรับมุมมอง คุณอาจสังเกตเห็นแล้วว่าหน้ามีชุดแอตทริบิวต์ที่ loaded
โดยการตั้งค่าแอตทริบิวต์นี้ ฉันบอกให้มุมมองเรียกใช้ฟังก์ชัน JavaScript เฉพาะเมื่อโหลดหน้าเว็บ
ฟังก์ชัน JavaScript นี้ถูกกำหนดไว้ในไฟล์ JS ขึ้นอยู่กับ สามารถเข้าถึงได้โดยเพียงแค่ส่งออกโดยใช้ exports.something
ในการเพิ่มการโยงข้อมูล สิ่งที่เราต้องทำคือตั้งค่า Observable ใหม่ให้กับคุณสมบัติหน้า bindingContext
Observables ใน NativeScript จะปล่อยเหตุการณ์ propertyChange
ซึ่งจำเป็นต่อการตอบสนองต่อการเปลี่ยนแปลงข้อมูลภายใน 'iews แต่คุณไม่ต้องกังวลกับเรื่องนั้น เนื่องจากใช้งานได้ทันที
const context = new Observable({ entries: null}); const fetchModule = require('fetch'); // export loaded to be called from // List.xml when everything is loaded exports.loaded = (args) => { const page = args.object; page.bindingContext = context; fetchModule.fetch( `https://cdn.contentful.com/spaces/${config.space}/entries?access_token=${config.cda.token}&content_type=event&order=fields.start`, { method: "GET", headers: { 'Content-Type': 'application/json' } } ) .then(response => response.json()) .then(response => context.set('entries', response.items)); }
สิ่งสุดท้ายคือการดึงข้อมูลและตั้งค่าให้เป็นบริบท สามารถทำได้โดยใช้โมดูล fetch
NativeScript ที่นี่คุณสามารถเห็นผล
อย่างที่คุณเห็น การสร้างรายการอย่างง่ายโดยใช้ NativeScript นั้นไม่ยากเลย ต่อมาฉันขยายแอปด้วยมุมมองอื่นรวมถึงฟังก์ชันเพิ่มเติมเพื่อเปิดที่อยู่ใน Google Maps และมุมมองเว็บเพื่อดูเว็บไซต์ของกิจกรรม
สิ่งหนึ่งที่ต้องชี้ให้เห็นที่นี่คือ NativeScript ยังค่อนข้างใหม่ ซึ่งหมายความว่าปลั๊กอินที่พบใน npm มักจะไม่มีการดาวน์โหลดหรือติดดาวจำนวนมากบน GitHub สิ่งนี้ทำให้ฉันหงุดหงิดในตอนแรก แต่ฉันใช้องค์ประกอบดั้งเดิมหลายอย่าง (nativescript-floatingactionbutton, nativescript-advanced-webview และ nativescript-pultorefresh) ซึ่งช่วยให้ฉันบรรลุประสบการณ์ดั้งเดิมและทำงานได้ดีอย่างสมบูรณ์
คุณสามารถดูผลลัพธ์ที่ดีขึ้นได้ที่นี่:
ยิ่งฉันใส่ฟังก์ชันการทำงานลงในแอพนี้มากเท่าไหร่ ฉันก็ยิ่งชอบมันมากเท่านั้นและยิ่งใช้มันมากขึ้นเท่านั้น ส่วนที่ดีที่สุดคือ ฉันสามารถกำจัดข้อมูลซ้ำซ้อน จัดการข้อมูลทั้งหมดในที่เดียว มีความยืดหยุ่นเพียงพอที่จะแสดงผลในกรณีการใช้งานต่างๆ
หน้าคือเมื่อวาน: เนื้อหาที่มีโครงสร้างยาวนาน!
การสร้างแอปนี้แสดงให้ฉันเห็นอีกครั้งว่าหลักการของการมีข้อมูลในรูปแบบหน้าเว็บเป็นเรื่องของอดีต เราไม่รู้ว่าข้อมูลของเราจะไปอยู่ที่ใด — เราต้องพร้อมสำหรับกรณีการใช้งานที่ไม่จำกัดจำนวน
เมื่อมองย้อนกลับไป สิ่งที่ผมทำได้คือ
- มีระบบจัดการเนื้อหาบนคลาวด์
- ไม่ต้องจัดการกับการบำรุงรักษาฐานข้อมูล
- สแต็คเทคโนโลยี JavaScript ที่สมบูรณ์
- มีเว็บไซต์แบบคงที่ที่มีประสิทธิภาพ
- มีแอพ Android เพื่อเข้าถึงเนื้อหาของฉันทุกที่ทุกเวลา
และส่วนที่สำคัญที่สุด:
การมีโครงสร้างและเข้าถึงเนื้อหาของฉันได้ช่วยให้ฉันสามารถปรับปรุงชีวิตประจำวันได้
กรณีการใช้งานนี้อาจดูเล็กน้อยสำหรับคุณในตอนนี้ แต่เมื่อคุณนึกถึงผลิตภัณฑ์ที่คุณสร้างทุกวัน จะมีกรณีการใช้งานสำหรับเนื้อหาของคุณบนแพลตฟอร์มต่างๆ มากขึ้นอยู่เสมอ วันนี้ เรายอมรับว่าในที่สุดอุปกรณ์พกพาก็แซงหน้าสภาพแวดล้อมเดสก์ท็อปแบบเก่า แต่แพลตฟอร์มอย่างรถยนต์ นาฬิกา และแม้แต่ตู้เย็นก็กำลังรอสปอตไลท์ของพวกเขาอยู่ นึกไม่ถึงว่าจะมีการใช้งานอะไรบ้าง
ให้พยายามเตรียมพร้อมและวางเนื้อหาที่มีโครงสร้างไว้ตรงกลาง เพราะสุดท้ายแล้ว มันไม่ได้เกี่ยวกับสคีมาของฐานข้อมูล แต่เป็นการ สร้างสำหรับอนาคต
อ่านเพิ่มเติม เกี่ยวกับ SmashingMag:
- การขูดเว็บด้วย Node.js
- ล่องเรือด้วย Sails.js: กรอบงานสไตล์ MVC สำหรับ Node.js
- 40 ไอคอนท่องเที่ยวเพื่อเสริมการออกแบบของคุณ
- บทนำโดยละเอียดเกี่ยวกับ Webpack