ฉันใช้เวลาในเว็บแอป Twitter สร้างขึ้นด้วย nextjs และ tailwindcss และทำงานกับแบ็กเอนด์ fastapi ของฉันที่ฉันสร้างขึ้นที่นี่ (https://github.com/dericf/twitter-clone-server-fastapi)
สิ่งนี้ถูกสร้างขึ้นเพื่อทำงานบนเดสก์ท็อปและมือถือ (โดยคาดว่าข้อบกพร่องบางอย่างบนมือถือ)
ทุกอย่างถูกเขียนเป็น typescript ตั้งแต่เริ่มต้นและใช้ async / await ทุกที่ที่เป็นไปได้
ฉันไม่ได้ลองและ "โคลน" Twitter และฟังก์ชั่นหรือการออกแบบทั้งหมด แต่ฉันออกแบบตัวเองให้มันตั้งแต่เริ่มต้น
เซิร์ฟเวอร์ได้รับการตั้งค่าเพื่อจัดการโทเค็น JWT ผ่านคุกกี้ HTTP-only หรือส่วนหัวการอนุญาต คุกกี้ใช้เพื่อให้สิ่งต่าง ๆ ง่าย
คำขอ fetch ทุกครั้งที่ต้องมีการรับรองความถูกต้องจะส่ง credentials: "include"
การอนุญาตเป็นพื้นฐานมาก - มีเพียง 1 ประเภทผู้ใช้และเซิร์ฟเวอร์ทำให้มั่นใจได้ว่าผู้ใช้จะเข้าถึง/แก้ไข/ลบทรัพยากรที่พวกเขาเป็นเจ้าของได้เท่านั้น
ผู้ใช้สามารถสร้างแก้ไขและลบทวีตรวมถึงดูทวีตที่โพสต์โดยผู้ใช้รายอื่น ปัจจุบันทวีตรองรับข้อความเท่านั้น ข้อความที่สมบูรณ์, รูปภาพ, ตัวอย่างลิงก์สด ฯลฯ อาจถูกนำไปใช้ในอนาคต
ผู้ใช้สามารถชอบและไม่เหมือนทวีตใด ๆ (รวมถึงความเรียบง่ายของคุณเอง)
ผู้ใช้สามารถสร้างแก้ไขและลบความคิดเห็นในทวีตใด ๆ (รวมถึงของคุณเอง)
ผู้ใช้สามารถชอบและไม่เหมือนความคิดเห็นใด ๆ (รวมถึงของคุณเองเพื่อความเรียบง่าย)
ผู้ใช้สามารถติดตามและไม่ติดตามผู้ใช้รายอื่นและดูรายชื่อผู้ใช้ที่พวกเขากำลังติดตามอยู่ในปัจจุบัน
ผู้ใช้สามารถดูรายชื่อผู้ใช้ทั้งหมดที่ติดตามได้ในปัจจุบัน
ฉันใช้การแชทแบบเรียลไทม์โดยใช้ websockets และตอบสนองตะขอ/บริบท ปัจจุบันไม่สนับสนุนการแชทเป็นกลุ่ม แต่อาจนำไปใช้ในอนาคต การแชทเป็นไปตามโมดอลดังนั้นจึงไม่ได้ขัดขวางการไหลของคุณเลยเพียงแค่เปิด/ปิดการแชทโมดัลจากหน้าใด ๆ โดยไม่ต้องเปลี่ยนเส้นทาง
ฉันใช้ TypeScript เพื่อกำหนดสคีมาที่เข้มงวดสำหรับข้อมูลที่ไหลไปและกลับจากเซิร์ฟเวอร์
ตัวอย่างของสคีมามีดังนี้สำหรับทวีต
import { APIResponse } from "./API" ;
import { EmptyResponse } from "./General" ;
export interface Tweet {
tweetId : number ;
userId : number ;
username : string ;
content : string ;
createdAt : string ;
}
export interface TweetCreateRequestBody {
content : string ;
}
export interface TweetUpdateRequestBody {
newContent : string ;
}
export type TweetResponse = APIResponse < Array < Tweet > > ;
export type TweetCreateResponse = APIResponse < Tweet > ;
export type TweetUpdateResponse = APIResponse < EmptyResponse > ;
export type TweetDeleteResponse = APIResponse < EmptyResponse > ; interface APIResponse<T> เป็นอินเทอร์เฟซทั่วไปที่กำหนดเองที่การตอบกลับแต่ละครั้งส่งคืน - แทนที่ประเภททั่วไป T ด้วยประเภทการส่งคืนที่เหมาะสมของจุดสิ้นสุดนั้นในคุณสมบัติที่เรียกว่า value
ตัวอย่างเช่น:
// T could be something like Array<CommentLike> or EmptyResponse
export interface APIResponse < T > {
value ?: T ;
error ?: APIResponseError ;
} class APIResponseError เป็นคลาส wrapper ที่ได้รับอินสแตนซ์เฉพาะเมื่อมีข้อผิดพลาด (สถานะการตอบกลับที่ไม่ใช่ 200 หรือข้อผิดพลาด typenscript ถูกโยนลง) คลาสมีวิธีการวัตถุ .errorMessageUI เพื่อให้มีข้อความที่เหมาะสมเพื่อแสดงผู้ใช้ในการแจ้งเตือนขนมปังหรือป๊อปอัพ
interface EmptyResponse ใช้เพื่อแสดงถึงประเภทของจุดสิ้นสุดที่ถูกกำหนดให้อย่างชัดเจนไม่ส่งคืนสิ่งใด - โดยปกติหลังจากการลบหรืออัปเดตบันทึก ฉันอาจจะใช้ null แต่ฉันต้องการที่จะชัดเจนและกำจัดการคาดเดาใด ๆ
สิ่งที่ต้องทำ
https://nextjs.org/
https://tailwindcss.com/
https://momentjs.com/
https://github.com/jossmac/react-toast-notifications
https://github.com/jedwatson/react-select
สร้างไฟล์ .env และเพิ่มตัวแปรต่อไปนี้:
NEXT_PUBLIC_API_URL="http://localhost:<SERVER_PORT>"
NEXT_PUBLIC_API_WS_URL="ws://localhost:<SERVER_PORT>/ws"
เรียกใช้ npm install จากนั้นเรียกใช้ npm run dev เพื่อเริ่มเซิร์ฟเวอร์การพัฒนาถัดไป
ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์แบ็กเอนด์ของคุณกำลังทำงานอยู่ (พอร์ตเริ่มต้น 8001)
วิธีที่ง่ายที่สุดในการปรับใช้คือ vercel เพียงสร้างโครงการ vercel ใหม่ที่เชื่อมโยงกับ GIT repo และเพิ่ม NEXT_PUBLIC_API_URL และ NEXT_PUBLIC_API_WS_URL ที่ชี้ไปที่เซิร์ฟเวอร์ API ที่โฮสต์ของคุณ
ในการปรับใช้เวอร์ชันใหม่เพียงแค่ git push เป็น master/main สำหรับการปรับใช้การผลิตหรือผลักดันไปยังสาขาที่ไม่ใช่ master/main สำหรับการปรับใช้ตัวอย่าง/การจัดเตรียม
ในที่สุดฉันก็อยากจะพัฒนาเวิร์กโฟลว์ที่ราบรื่นสำหรับการปรับใช้ NextJs ด้วย Docker มันควรจะตรงไปตรงมาเนื่องจากไม่มีการใช้ฟังก์ชั่นที่ไม่มีเซิร์ฟเวอร์