วิธีเช่า Hosting ฟรีๆที่ Parse.com

Published on
Web Development
2014/07/how-to-hosting-website-with-parse
Discord

Cover Image: parse.com

หากใครยังจำกันได้ ผมได้เคยพูดเกี่ยวกับ Pares.com ไปแล้วในหัวข้อ มาทำความรู้จักกับ Parse.com กัน และเขียนบทความเกี่ยวกับ Parse.com ไปแล้ว 2 บทความ ซึ่งเป็นการใช้งาน Parse ร่วมกับแอพ Android แต่ว่าในบทความนี้ จะไม่มีส่วนเกี่ยวข้องกับ Android เลย แต่เป็นการใช้อีก feature หนึ่งของ Parse นั้นก็คือในส่วน Cloud Code และ Hosting นั่นเอง

หากใครที่กำลังมองหา Hosting ไว้สำหรับทำเว็บ ลองมาใช้ Parse เป็นโฮสดูได้ครับ ฟรี และสามารถทำ Custom Domain ได้อีกต่างหาก

Prerequisite

เนื้อหาที่จะใช้ในบทความนี้ แนะนำให้อ่านจาก Docs ประกอบด้วยนะครับ

ในส่วนบทความนี้ เป้าหมายคือทำเว็บไซต์ทั้งแบบ Static และ Dynamic ด้วย Parse Hosting รวมถึงการดึงข้อมูลจาก Parse Data มาแสดงในเว็บไซต์ได้ ความรู้และเทคโนโลยีที่ใช้ในบทความนี้ประกอบไปด้วย

  • HTML, CSS, Javascript เบื้องต้น
  • Node.js : ควรจะรู้จัก Node.js ซักนิดนึง เป็นพื้นฐานประกอบครับ หากใครไม่รู้จัก แนะนำอ่านนี้ก่อน AN ABSOLUTE BEGINNER'S GUIDE TO NODE.JS
  • Express.js : ตัวนี้เป็น Node Framework ครับ ใน Parse API จะใช้ Express 3.1.0 ซึ่งตัวปัจจุบัน Express เป็น 4 แล้ว แนะนำ ให้อ่านของ Express Parse API ด้านบนประกอบครับ
  • Command Line: หากใครใช้ Windows ก็ต้องโหลด Parse Console จาก ลิงค์นี้ด้วย
  • Render Template : ในบทความนี้จะใช้ Render Template ชื่อว่า EJS โดย TJ (My Idol)

Getting Started

เริ่มต้นเลย ให้สร้าง App ของ Parse ก่อนเลยครับ ไปที่ Dashboard เลือก Create New App

Create new Site

เมื่อสร้างแอพแล้ว ก็ไปแท็บ Settings เลือก Web Hosting จากนั้นก็ใส่ subdomain เพื่อจะเอาไว้เข้าเว็บไซต์ของเรา (เว็บเรายังเป็น subdomain ของ parse อยู่นะครับ) อย่างของผมตั้งไว้ เวลาเข้าเว็บไซต์ ก็จะเข้าผ่าน http://devahoy.parseapp.com

Subdomain

Note: ในส่วน Custom Domain ไม่รวมอยู่ในบทความนี้นะครับ ไปลองทำกันเองครับ ไม่เสียตังเพิ่มนะครับ ฟรี!

ต่อมาถึงเวลาของ Command Line แล้ว สำหรับเครื่อง (Mac/Linux) ให้ทำการ install ด้วยคำสั่ง

curl -s https://www.parse.com/downloads/cloud_code/installer.sh | sudo /bin/bash

ส่วน Windows โหลด Parse Console ครับ

Create Project

เมื่อทำการติดตั้ง Parse Command Line เรียบร้อยแล้ว ต่อมาก็จะทำการสร้างโฟลเดอร์ของโปรเจ็คของเราครับ ด้วยคำสั่ง

parse new yourProjectName

yourProjectName คือใส่่ชื่อของโฟลเดอร์ของเรานะครับ จากนั้น parse จะทำการสร้างโฟลเดอร์ให้เรา อย่างเช่น ผมสร้างโฟลเดอร์ชื่อ devahoy-site ดังนี้

parse new devahoy-site

Creating a new project in directory /home/phonbopit/Desktop/devahoy-site
Creating directory /home/phonbopit/Desktop/devahoy-site/config
Creating config file /home/phonbopit/Desktop/devahoy-site/config/global.json
Creating directory /home/phonbopit/Desktop/devahoy-site/cloud
Writing out sample file /home/phonbopit/Desktop/devahoy-site/cloud/main.js
Creating directory /home/phonbopit/Desktop/devahoy-site/public
Writing out sample file /home/phonbopit/Desktop/devahoy-site/public/index.html
Email: captain@devahoy.com
Password:
1: BallThai
2: Bluelight
3: ChaiPic 0.0.1
4: DevahoyParse
5: RTTest 0.0.1
6: Yakdeal_Sandbox
7: devahoy_site
8: swthailand
9: ngRouter
Select an App: 7

cd devahoy-site

ให้ใส่อีเมล์ และพาสเวิร์ด ที่ใช้ในการลอคอินเข้า Parse จากนั้นก็เลือก แอพของเรา ในกรณีที่ได้สร้างไว้หลายแอพ ก็เลือกตัวเลขของแอพเลยครับ

เมื่อดูที่โฟลเดอร์ที่ Parse สร้างไว้ให้ จะเห็น File Structure ดังนี้

├── cloud
│   └── main.js
├── config
│   └── global.json
└── public
    └── index.html
  • โฟลเดอร์ cloud: สำหรับจัดการ Cloud Code ของเรา
  • โฟลเดอร์ config: ตัวนี้เป็นตัว config Parse จะเห็นว่ามี applicationId และ masterkey อยู่ซึ่งได้จากการที่เราลิงค์แอพตอน Select App ก่อนหน้านั่นเอง
  • โฟลเดอร์ public : อันนี้จะเป็นส่วนหน้าเว็บไซต์ เช่นพวกไฟล์ html หรือจะเป็น image, stylesheet เป็นต้น

Deploy Static Website

โอเค ทดสอบ Deploy ขึ้น Hosting ดูก่อน ด้วยคำสั่ง

parse deploy


Uploading source files
Finished uploading files
New release is named v1 (using Parse JavaScript SDK v1.2.18)

ทดสอบเข้าหน้าเว็บไซต์ จากที่เรากำหนด subdomain ไปแล้ว http://devahoy.parseapp.com จะเจอหน้าตาแบบนี้

Static Parse

โอเค เรียบร้อยแล้ว ตอนนี้เราสามารถทำเว็บไซต์แบบ Static Website ได้แล้ว ทีนี้ลองเพิ่มหน้าอื่นๆบ้าง เช่น index.html หรือ about.html แล้วลองเข้าเว็บไซต์ โดยเป็น path ตามชือ่ไฟล์ เช่น http://devahoy.parseapp.com/about.html

Dynamic Website

การทำ Static Website มันดูเป็นเรื่องพื้นฐานไปซะหน่อย มาถึงการทำ Dynamic Website กันเลยดีกว่า สำหรับการทำ Dynamic Website บน Parse นั้นจะใช้ Express.js โดยการ generate ได้ด้วยคำสั่งนี้

cd devahoy-site
parse generate express

สามารถ generate ได้จากโฟลเดอร์ของ parse เราก่อนหน้านี้ได้เลยครับ จะเห็นว่ามีไฟลถูกสร้างเพิ่มในโฟลเดอร์ cloud

├── cloud
│   ├── app.js
│   ├── main.js
│   └── views
│       └── hello.ejs

แต่ว่ายังไม่เสร็จ สังเกตเห็นข้อความว่า

Almost done! Please add this line to the top of your main.js:

    require('cloud/app.js');

ให้เราเปิด ไฟล์ cloud/main.js จากนั้นทำการเพิ่ม ไว้ด้านบนของไฟล์เลย

require('cloud/app.js');

เพื่อทำการ include ทั้งหมดที่เรา config ไว้ใน app.js นั่นเอง เหมือนการ import ใน Java หรือการ include ในภาษา C, PHP

ต่อมา มาทำความเข้าใจโค๊ดข้างในไฟล์ app.js กันก่อนดีกว่า

// These two lines are required to initialize Express in Cloud Code.
var express = require('express')
var app = express()

// Global app configuration section
app.set('views', 'cloud/views') // Specify the folder to find templates
app.set('view engine', 'ejs') // Set the template engine
app.use(express.bodyParser()) // Middleware for reading request body

โค๊ดด้านบนเป็นการเรียกใช้ Express.js จากนั้นทำการ config โดยใช้ View Engine ที่ชื่อว่า ejs โดยจะมองหาไฟล์ที่อยู่ในโฟลเดอร์ cloud/views

ต่อมา

app.get('/hello', function (req, res) {
  res.render('hello', { message: 'Congrats, you just set up your app!' })
})

เป็นการ route โดยเมื่อเรา request URI เป็น http://devahoy.parseapp.com/hello ก็จะทำการ render ไฟล์ /views/hello.ejs โดยส่งพารามิเตอร์คือ message ไปด้วย

ลองเปิดไฟล์ hello.ejs ดู จะพบว่า

<%= message %>

ซึ่งตรงนี้ มันคือการแทรกโค๊ดลงไปในหน้า html (หากใครเคยเขียน Ruby .erb หรือว่า พวก Mustache, Handlebars, Liquid ก็จะคล้ายๆกันนั่นแหละครับ )

สั่งรัน Deploy แล้วลองเข้าหน้าเว็บ /hello ดูครับ เริ่มมาถูกทางแล้ว กับการทำ Dynamic Website แต่คิดว่ายังคงไม่เห็นภาพ ฉะนั้น ต่อมา เรามาทำเว็บโดยดึงข้อมูลจาก Data มาแสดงซะเลยดีกว่า

ไปที่ Data Browser เลือก New Class แล้วจัดการเพิ่มคลาสใหม่ลงไป ผมตั้งชื่อว่า Player เพื่อเอาไว้แสดงรายชื่อนักฟุตบอลครับ :D

สามารถ import data ของบทความนี้ไปใส่ได้เลย ครับ เอาโค๊ดจากนี้ไป import เลือกไฟล์ แล้วก็ตั้งชื่อคลาสว่า Player

จากนั้นผมเพิ่ม Columns : Name, Club, Age, National เพิ่มเข้าไปดังนี้

Data Browser

เพิ่มข้อมูล Sample ลงไป เป็นแบบนี้

Sample Data

ต่อมา กลับมาที่ไฟล์ app.js โดยเราจะทำการ route หน้านี้ /player แล้วให้ทำการ Query ข้อมูล player ใน data ของเราครับ

app.get('/players', function (req, res) {})

ต่อมาเราจะใช้ Parse Cloud เข้ามาช่วย จะได้เป็นแบบนี้

app.get('/players', function (req, res) {
  Parse.Cloud.run(
    'findPlayers',
    {},
    {
      success: function (result) {
        res.render('index', { players: result })
      },
      error: function (error) {}
    }
  )
})

ตัว Parse.Cloud.run() รับ parameter 3 ตัวคือ findPlayers เป็น function ที่เราจะ define (ตอนนี้ยังไม่ได้สร้าง), ตัวสอง ไม่ได้ส่ง data params อะไรไป ส่วนอันสามเป็น Options โดยเรามี 2 ฟังค์ชันคือ success และ error เมื่อ success ก็จะให้ทำการ render หน้า views/index.ejs โดยส่งออปเจ็คที่เรา query ได้ไปในชื่อ players (ไฟล์ index.ejs ยังไมไ่ด้สร้าง)

ต่อมา ทำการ define ฟังค์ชั่น findPlayer โดยเปิดไฟล์ cloud/main.js แล้วเพิ่มโค๊ดข้างล่างนี้ลงไป

Parse.Cloud.define('findPlayers', function (req, res) {
  var query = new Parse.Query('Player')
  query.find({
    success: function (results) {
      res.success(results)
    },
    error: function () {
      res.error('not found players')
    }
  })
})

ด้านบนเป็น query ออปเจ็คของ Parse แบบธรรมดาเลย ไม่มีกำหนดเงื่อนไขเลย แล้วส่งผลลัพธ์ไปแสดงในหน้า view หากใครอยากรู้รายละเอียดการ Query Parse เพิ่มเติม ให้อ่านหัวข้อนี้ Javascript Parse Query

ต่อมา เพิ่มไฟล์ views/index.ejs แบบนี้ (ในตัวอย่างผมใช้ Zurn Foundation นะครับ โหลดไฟล์ foundation.min.css แล้วเซฟไว้ที่ public/css/)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Players</title>
    <link rel="stylesheet" href="../css/foundation.min.css" />
  </head>
  <body>
    <div class="row">
      <h1>List of Players</h1>
    </div>

    <div class="row">
      <% players.forEach(function(player) { %>
      <div class="panel medium-4 columns">
        <h3>
          <a href="/players/<%= player.id %>"><%= player.get('name') %></a>
        </h3>
        <p>Age: <%= player.get('age') %></p>
        <p>Club: <%= player.get('club') %></p>
        <p>National: <%= player.get('national') %></p>
      </div>
      <% }) %>
    </div>
  </body>
</html>

สังเกต เวลาเราจะเข้าถึง object ของ parse เราจะใช้คำสั่ง get('name') แล้วตามด้วยชื่อของ column นั้นๆ

เมื่อเปิดเว็บไซต์ http://devahoy.parseapp.com/players จะได้หน้าตาแบบนี้

Player List

แต่เดี่ยวก่อน สังเกตว่าผมมีลิงค์ โดยกดจากชื่อ Player แล้วไปเปิดหน้าใหม่ด้วย ซึ่ง route มันก็คือ player/:id นั่นเอง ก็ต้องมาทำการเพิ่ม route ที่ไฟล์ app.js อีกครั้ง ดังนี้

app.get('/players/:id', function (req, res) {
  Parse.Cloud.run(
    'findPlayerById',
    { id: req.params.id },
    {
      success: function (result) {
        res.render('player', { players: result })
      },
      error: function (error) {}
    }
  )
})

โค๊ดด้านบน เหมือนกับตอนเรา route /players เลยครับ ต่างกันที่เราส่ง parameter เป็น id ส่งไปด้วย ต่อมาก็ define function findPlayerById ในไฟล์ cloud/main.js เลย

Parse.Cloud.define('findPlayerById', function (req, res) {
  var query = new Parse.Query('Player')
  query.get(req.params.id, {
    success: function (results) {
      res.success(results)
    },
    error: function () {
      res.error('not found player')
    }
  })
})

คล้ายๆกับฟังค์ชัน findPlayers ต่างกันที่ฟังค์นี้ใช้การ query โดยระบุ objectId ของ parse นั่นเอง อ่านเพิ่มเติมเกี่ยวกับการ Query ได้ที่นี่ Retreiving Object

อ้อก่อนจบ ลืมไปว่า เรา render ด้วย player ฉะนั้นก็ต้องสร้าง view ชื่อ player.ejs ด้วย ดังนี้

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Players</title>
    <link rel="stylesheet" href="../css/foundation.min.css" />
  </head>
  <body>
    <div class="row">
      <h1 class="medium-4 large-centered columns">Player Detail</h1>
    </div>

    <div class="row">
      <div class="panel medium-4 large-centered columns">
        <h3><%= player.get('name') %></h3>
        <p>Age: <%= player.get('age') %></p>
        <p>Club: <%= player.get('club') %></p>
        <p>National: <%= player.get('national') %></p>

        <a href="../players" class="button large radius expand">BACK</a>
      </div>
    </div>
  </body>
</html>

สุดท้ายเมื่อกดเข้าหน้า Player แต่ละคน ก็จะได้หน้าตาประมาณนี้

Player Detail

Source Code

โค๊ดทั้งหมด อัพลง Github แล้ว นำไปศึกษาได้ครับ จริงๆ มันก็นำไปใช้ได้เลย เพียงแค่เปลี่ยน applicationId และ masterKey ใน config/global.js ด้วยละครับ

Source on Github

Buy Me A Coffee
Authors
Discord