Menu

Wednesday, February 17, 2021

[Laravel - Composer] วิธีการใช้ Custom Package พร้อมกับการกำหนด Version ของ Package นั้นในไฟล์ composer.json
[Laravel - Package] How to Use Your Custom Package with Package Version in Composer File

ไฟล์ composer.json เป็นแหล่งรวมรายการ package ที่ต้องใช้ใน Laravel project

บางครั้งเราอาจจะต้อง fork package บางตัวมาจาก repository อื่น เพื่อนำมาปรับใช้กับ project ของเรา

หลังจากที่เราปรับแก้ package แล้ว เรามีวิธีตั้งค่าไฟล์ composer เพื่อเรียกใช้ package จาก branch บน repository ของเราดังนี้
  1. เพิ่มชื่อ package ของเราในส่วน require หรือ require-dev ดังนี้
    "require": {
        ...
        "{package_name}": "dev-{branch_name}",
        ...
    }
    เช่น
    "require": {
        ...
        "monolog/monolog": "dev-fix-concurrent-mkdir",
        ...
    }
  2. เพิ่ม repository ของเราในส่วน repositories ดังนี้
    "repositories": {
        ...
        {
          "type": "vcs",
          "url": "{my_repository_url}"
        },
        ...
    }
    เช่น
    "repositories": {
        ...
        {
          "type": "vcs",
          "url": "https://github.com/my_repo/monolog.git"
        },
        ...
    }

Tuesday, February 9, 2021

[Bash Script] ข้อควรระวัง: ควรใช้ Full Path ของ Command ใน Bash Script
[Bash Script] Beware: Should Use Full Path of Command in Bash Script

เคสนี้เกิดขึ้นหลังจากที่เราเขียน bash script แล้วนำไปรันจริง ปรากฏว่า script นั้นสามารถรันบนเครื่อง UAT ได้ อย่างไม่มีปัญหาอะไร แต่เมื่อนำ script นั้นไปรันบนเครื่อง Production กลับไม่มีอะไรเกิดขึ้น 

สาเหตุที่พบ คือ การสั่งรัน command ใน script ที่เราเขียนนั้น เราเรียก command นั้นเลย โดยไม่ได้ใส่เป็น full path ของ command เอาไว้ มีความเป็นไปได้ว่า script อาจจะไม่สามารถหาที่อยู่ของ command นั้นได้

วิธีแก้ไข คือ เปลี่ยน command ที่ถูกเรียกใช้ใน script เป็น full path ทั้งหมด จึงทำให้ script นี้สามารถรันบนเครื่อง Production ได้ตามปกติ

คำแนะนำ เพื่อหลีกเลี่ยงจากเคสข้างบน เราแนะนำให้ใช้ full path ของ command ทั้งหมด ถ้าหากไม่ทราบ full path อาจจะใช้ which command ช่วย (สามารถอ่าน)

[Bash Script] วิธีการรันคำสั่งที่เก็บอยู่ในตัวแปร
[Bash Script] How to Run Command that Store in Variable

จากโพสต์ [Bash Script] วิธีการประกาศและใช้ตัวแปรใน Bash Script ที่เราสามารถเก็บค่าผลลัพธ์จากการรันคำสั่งอื่นๆใส่ในตัวแปรได้

สมมติว่า เรามีตัวแปร ชื่อ command ที่เก็บค่าดังนี้

command=$(which echo)

ในที่นี้ command จะมีค่าเป็น /bin/echo

ถ้าหากเราต้องการนำค่าของ command ไปเป็นคำสั่งในการรันต่อ เราจะใช้คำสั่งดังนี้

$command "echo_string"

เราจะเห็นได้ว่า command จะมี $ นำหน้า เพื่อแทนที่ตัวแปรนั้นด้วยค่าของมัน แล้วตามด้วย parameter ที่จะส่งเข้าไปยังคำสั่งนั้นๆ ซึ่งบรรทัดข้างบนจะมีค่าเท่ากับ

/bin/echo "echo_string"

Tuesday, February 2, 2021

[GIT] วิธีการเพิ่ม Remote URL ของ GIT Repository
[GIT] How to Add New Remote URL of GIT Repository

 การเปลี่ยน Remote URL ของ GIT Repository จำเป็นต้องใช้ 2 คำสั่งดังนี้

  • คำสั่งสำหรับตรวจสอบ GIT remote URL ปัจจุบัน
    git remote -v
  • คำสั่งสำหรับตั้งค่า Remote URL ของ GIT Repository ใหม่
    git remote add <new_remote_name> <new_git_remote_url>
ตัวอย่างการใช้งาน เช่น
$ git remote -v
origin  git@github.com:username/project.git (fetch)
origin  git@github.com:username/project.git (push)
$ git remote add test git@github.com:username/project2.git
$ git remote -v 
origin  git@github.com:username/project.git (fetch)
origin  git@github.com:username/project.git (push)
test git@github.com:username/project2.git (fetch)
test git@github.com:username/project2.git (push)

ข้อมูลเพิ่มเติม สามารถอ่านได้ที่ Adding a remote

Monday, February 1, 2021

[NodeJS - NestJS] วิธีการตั้งค่า Metadata ที่ Class แทน Handler เพื่อใช้ตรวจสอบสิทธิ์การใช้งาน
[NodeJS - NestJS] How to Set Metadata to Class instead of Handler for Authorization

เราสามารถใช้ Guards ในการตรวจสอบสิทธิ์การใช้งานของผู้ใช้

จากตัวอย่างใน Setting roles per handler เป็นการเช็คสิทธิ์แยกตาม handler ใน controller โดยเราจะตั้งค่า permissions ผ่านทาง @SetMetadata เหนือ handler นั้นๆดังนี้

@SetMetadata('permissions', ['create_user'])
async create(@Body() createUserDto: CreateUserDto) {
    this.userService.create(createUserDto);
}

และมีวิธีเรียกใช้ค่า permissions ใน Guard ดังนี้ 

const permissions = this.reflector.get<string[]>('permissions', context.getHandler());

อย่างไรก็ตาม เราสามารถตั้งค่า roles สำหรับ controller นั้นๆแทน handler ได้ ถ้าหากทุก handler ใน controller นั้นๆ ใช้สิทธิ์เดียวกันทั้งหมด โดยเราจะตั้งค่า permissions ผ่านทาง @SetMetadata เหนือ class ของ controller นั้นๆดังนี้ 

@SetMetadata('permissions', ['create_user'])
export class Controller {
    async create(@Body() createUserDto: CreateUserDto) {
        this.userService.create(createUserDto);
    }
}

และมีวิธีเรียกใช้ค่า permissions ใน Guard ดังนี้ 

const permissions = this.reflector.get<string[]>('permissions', context.getClass()); 

หมายเหตุ เราจะสังเกตได้ว่า parameter ตัวที่ 2 ของ this.reflector.get() มีความแตกต่างกัน ถ้าเราต้องการดึงค่า Metadata จาก handler เราจะใช้ context.getHandler() แต่ถ้าเราต้องการดึงค่า Metadata จาก class เราจะใช้ context.getClass() แทน