paint-brush
Hành trình 4 năm của tôi để xây dựng mạng xã hội với tư cách là nhà phát triển một mìnhtừ tác giả@mariostopfer
651 lượt đọc
651 lượt đọc

Hành trình 4 năm của tôi để xây dựng mạng xã hội với tư cách là nhà phát triển một mình

từ tác giả Mario Stopfer2022/10/18
Read on Terminal Reader
Read this story w/o Javascript

dài quá đọc không nổi

Nhằm mục đích cung cấp cho người tạo nội dung khả năng tương tác với cộng đồng của họ và để họ đóng góp vào quá trình tạo nội dung, đồng thời có thể kiếm tiền từ nỗ lực của họ, tất cả ở cùng một nơi. Ý tưởng xây dựng một nền tảng truyền thông xã hội xuất phát từ mong muốn không chỉ tạo ra nội dung với tư cách cá nhân mà còn gắn kết với cộng đồng. Bản thân nền tảng này, nếu nó muốn có sẵn cho càng nhiều người càng tốt, thì nó cần phải là một trang web và hầu như không có kinh nghiệm phát triển web, điều này dường như không thể đạt được. Để nghĩ rằng điều này sẽ không dễ dàng sẽ là một cách nói của thế kỷ.
featured image - Hành trình 4 năm của tôi để xây dựng mạng xã hội với tư cách là nhà phát triển một mình
Mario Stopfer HackerNoon profile picture
0-item


Đây là một câu chuyện, một sự phơi bày đầy đủ, về dự án solo-dev của tôi, Cộng đồng nhập vai - Nền tảng truyền thông xã hội dành cho người sáng tạo nội dung, mà tôi đã thực hiện vào đầu năm 2018 và hoàn thành vào năm 2022.


Tôi hy vọng nó sẽ là một hướng dẫn cho bất kỳ ai đang bắt đầu một dự án lớn hoặc đang trong quá trình xây dựng một dự án và cần động lực để tiếp tục.

Ý tưởng

Vào đầu năm 2018, những giọng ca yếu ớt bắt đầu nổi lên. Mọi người bắt đầu nói lên ý kiến của họ về trạng thái của web và mạng xã hội nói chung.


Một số người không hài lòng với Facebook và các chính sách của Facebook về quyền riêng tư của người dùng, những người khác phàn nàn về YouTube và các hoạt động kiếm tiền của nó, trong khi đó, những người khác lại phản đối chính những nền tảng mà họ đang nói lên quan điểm của mình như Medium.com.


Nhưng giải pháp thay thế cho tất cả những thứ này sẽ như thế nào?

Dự án Solo-Dev - Lịch sử hình thành

Ý tưởng xây dựng một nền tảng truyền thông xã hội xuất phát từ mong muốn mang đến cho người tạo nội dung khả năng, không chỉ tạo ra nội dung với tư cách cá nhân mà còn tương tác với cộng đồng của họ và để họ đóng góp vào quá trình tạo nội dung trong khi có thể kiếm tiền từ nỗ lực của họ ; tất cả ở một địa điểm.


Nền tảng phải được sử dụng miễn phí và bất kỳ ai cũng có thể tham gia. Không cần phải nói rằng những người sáng tạo, những người đầu tư thời gian vào công việc của họ, nhằm giáo dục và giải trí cho mọi người trên khắp thế giới, cũng có thể kiếm sống từ những gì họ yêu thích.


Liệu điều này có giải quyết được tất cả các vấn đề mà chúng ta gặp phải trực tuyến ngày nay không? Không, nhưng đó là một sự thay thế, và đó là những gì quan trọng. Đó là một hạt giống, theo thời gian, có thể biến thành một thứ gì đó đẹp đẽ.


Là một nhà công nghệ, tôi cũng tự hỏi liệu tất cả những điều này có thể được thực hiện bởi một người duy nhất hay không.


Liệu một người có thể thực sự vượt qua thử thách và cung cấp một nền tảng cấp doanh nghiệp mạnh mẽ mà mọi người sẽ thích sử dụng hay không, và nếu có, thì sẽ cần những gì để cung cấp một hệ thống như vậy?


Thành thật mà nói, tôi không có câu trả lời cho những câu hỏi đó, nhưng tôi quyết định chấp nhận thử thách.


Vào những ngày đầu năm 2018, tôi chỉ có khoảng 6 năm kinh nghiệm làm việc với tư cách là nhà phát triển phần mềm, chủ yếu là .NET back-end và một số WPF ở front end.


Tôi cũng đang sống ở Tokyo, nơi tôi chuyển đến cách đây chưa đầy 3 năm, và làm thêm giờ là tiêu chuẩn; Ý tưởng về việc thực hiện thêm công việc, cho tất cả các ý định và mục đích là không hợp lý, ít nhất phải nói rằng.


Bản thân nền tảng này, nếu nó muốn có sẵn cho càng nhiều người càng tốt, thì nó cần phải là một trang web và hầu như không có kinh nghiệm phát triển web, điều này dường như không thể đạt được.


Thực tế là điều đó dường như không thể, chính xác là lý do tại sao tôi quyết định bắt đầu sớm hơn là muộn. Tất cả những điều này sẽ là một sự lãng phí thời gian khổng lồ? Chỉ có thời gian mới trả lời được, nhưng tôi bắt đầu càng sớm thì tôi càng sớm tìm ra câu trả lời.


Sau đó, vào ngày 1 tháng 2 năm 2018 , tôi bắt đầu lập kế hoạch.

2018 - Kế hoạch

Điều đầu tiên tôi quyết định làm là tự nhủ rằng điều này sẽ không dễ dàng, sẽ là cách nói của thế kỷ. Tôi chưa bao giờ làm bất cứ điều gì như thế này trước đây, vì vậy tôi thực sự không biết mình đang vướng vào điều gì.


Điều này có nghĩa là không có sở thích hoặc bất cứ điều gì giống với cuộc sống cho đến khi điều này được hoàn thành. Làm thêm giờ ở công việc toàn thời gian của tôi và sau đó trở về nhà và làm việc trong dự án này, sẽ trở thành một tiêu chuẩn mới.


Tôi sẽ đi nghỉ và đi du lịch vào một lúc nào đó? Có, nhưng tôi sẽ phải dành những kỳ nghỉ này chủ yếu để làm việc.


Nếu tôi đã học được bất cứ điều gì từ kinh nghiệm trước đây của mình, thì việc có tổ chức là điều tạo nên hoặc phá vỡ dự án của bạn và giúp bạn đi đúng hướng. Bạn càng chuẩn bị và thiết kế trước, thì càng ít loại công việc bạn cần thực hiện sau này.


Suy nghĩ và lập kế hoạch chắc chắn dễ hơn xây dựng và tốn ít thời gian hơn, vì vậy tôi càng làm nhiều trong giai đoạn lập kế hoạch, tôi càng ít phải khám phá trong giai đoạn phát triển thực tế, vốn đòi hỏi nhiều nguồn lực hơn về thời gian.


Nguồn lực là thứ tôi không có, vì vậy tôi phải bù đắp điều đó bằng việc lập kế hoạch và thiết kế. Tôi cũng biết rằng web là nơi để đến khi tôi gặp khó khăn nhưng tôi quyết định sẽ không sử dụng Stack Overflow cho dự án này và hỏi bất kỳ câu hỏi mới nào.


Lý do đằng sau quyết định này khá đơn giản. Thấy ở đây sẽ học được rất nhiều thứ, nếu mình chỉ đi nhờ ai đó giải quyết mọi vấn đề của mình thì mình sẽ không rút ra được kinh nghiệm gì.


Càng về sau, dự án càng tiến triển, khó khăn hơn và tôi sẽ không có bất kỳ kinh nghiệm nào để tự mình giải quyết.


Vì vậy, tôi quyết định chỉ tìm kiếm trên web những câu trả lời đã có, nhưng không đặt câu hỏi mới để giải quyết vấn đề của mình. Sau khi dự án được thực hiện, tôi có thể tham gia lại với Stack Overflow, nhưng đối với mục tiêu phát triển cụ thể này, nó sẽ bị giới hạn.


Tôi sẽ sử dụng phương pháp OOAD để thiết kế hệ thống mà tôi muốn xây dựng. Hệ thống sẽ cho tôi biết cách hoạt động của từng bộ phận và cách nó tương tác với các bộ phận khác của hệ thống. Hơn nữa, tôi sẽ trích xuất các quy tắc kinh doanh mà sau này tôi sẽ triển khai trong mã.


Sau đó, tôi bắt đầu ghi chép và nhận ra có hai điểm chính mà tôi phải tập trung vào:


  • Thiết kế dự án
  • Tech Stack


Vì tôi biết rằng chỉ có 24 giờ trong một ngày và hầu hết trong số đó tôi sẽ dành cho công việc hoặc đi du lịch, nên tôi phải tối ưu hóa thời gian của mình một cách cẩn thận.

Thiết kế dự án

Đối với phần Thiết kế Dự án, để tiết kiệm tối đa thời gian của mình, tôi quyết định xem xét sản phẩm nào đã hoạt động tốt và sử dụng những sản phẩm đó làm nguồn cảm hứng.


Rõ ràng, hệ thống cần phải nhanh và có thể truy cập được cho tất cả mọi người và vì tôi không có thời gian để viết mã cho nhiều nền tảng, nên web chính là câu trả lời.


Sau đó tôi chuyển sang thiết kế. Apple nổi tiếng với các phương pháp thiết kế được chấp nhận tốt là nguồn cảm hứng tức thì. Tiếp theo, tôi chuyển sang Pinterest và quyết định rằng đây là thiết kế đơn giản nhất có thể hoạt động tốt. Ý tưởng đằng sau quyết định của tôi là một câu nói cũ.


Nội dung là vua. - Bill Gates, 1996.


Điều này đã cho tôi ý tưởng để loại bỏ càng nhiều chi tiết thiết kế không cần thiết càng tốt và tập trung vào việc trình bày nội dung. Nếu bạn nghĩ về nó, mọi người sẽ đến trang web của bạn một lần vì nó có thiết kế đẹp, nhưng họ sẽ không tiếp tục quay lại trừ khi bạn có nội dung tốt.


Điều này có tác dụng giảm thời gian thiết kế phần đầu xe.


Bản thân hệ thống phải đơn giản. Mọi người dùng đều có thể tạo và sở hữu cộng đồng của riêng họ. Những người dùng khác sẽ có thể tham gia với tư cách thành viên và viết bài để đóng góp nội dung cho cộng đồng này. Tính năng này sẽ được lấy cảm hứng từ Wikipedia, nơi nhiều người dùng có thể chỉnh sửa cùng một bài báo.


Nếu có nhiều người cùng tham gia vào một chủ đề nhất định, thì điều này cho chúng ta biết rằng những gì chúng ta có trong tay là một cộng đồng, và như vậy, nên tách biệt với phần còn lại.


Đối với các tính năng, người dùng không chỉ cần có khả năng viết các bài báo thông thường và kết nối chúng như Wikipedia mà còn có thể viết các bài đánh giá, điều này sẽ yêu cầu một loại bài viết khác.


Do đó, các bài báo thông thường sẽ được gọi là “Sở thích” và sẽ mang tính chất thực tế và thông tin, với bất kỳ ai cũng có thể chỉnh sửa chúng.


Mặt khác, "Bài đánh giá" sẽ dựa trên từng sở thích và chỉ tác giả của bài đánh giá mới có thể chỉnh sửa nó.


Nói tóm lại, mọi người có thể hợp tác viết về một bộ phim, giả sử như “The Matrix” và chỉnh sửa bài báo đó bất cứ khi nào họ muốn. Họ có thể thêm bất kỳ thông tin thực tế nào vào bài báo mà họ muốn.


Sau đó, mỗi người dùng sẽ có thể viết đánh giá của riêng họ về bộ phim đó. Đương nhiên, bài báo gốc sau đó sẽ hiển thị danh sách tất cả các bài đánh giá được viết cho bộ phim này.


Tôi thấy rõ ràng rằng tôi còn phải thêm hai tính năng quan trọng nữa. Đầu tiên sẽ là một tùy chọn tìm kiếm sẽ tìm kiếm các bài báo trong mỗi cộng đồng. Tính năng khác là các đề xuất, mà người dùng sẽ được phục vụ dựa trên những gì họ thích khi họ cuộn đến cuối bài viết.


Mỗi người dùng cũng có thể đăng các cập nhật ngắn hoặc “Hoạt động” lên hồ sơ của họ, hồ sơ này sẽ hoạt động như một Bức tường trên Facebook. Đây là phác thảo cơ bản mà tôi đã thực hiện trước khi bắt đầu nghĩ đến các công nghệ mà tôi có thể sử dụng để thực sự cung cấp dự án.

Ngăn xếp công nghệ

Điều thứ hai tôi tập trung vào là Tech Stack. Vì tôi đã quyết định sẽ xây dựng một dự án dựa trên web, nên tôi đã quyết định viết ra tất cả các công nghệ phổ biến và hiện đại được sử dụng phổ biến nhất vào thời điểm đó. Sau đó, tôi sẽ chọn những thứ về mặt kỹ thuật gần với những gì tôi đã sử dụng trong sự nghiệp của mình để dành ít thời gian nhất có thể để học các công nghệ mới.


Hơn nữa, ý tưởng khiến tôi suy nghĩ nhiều nhất trong giai đoạn này là đưa ra các quyết định thiết kế yêu cầu tôi viết càng ít mã càng tốt, do đó tiết kiệm thời gian.



Sau khi nghiên cứu sâu rộng, tôi đã quyết định trên Tech Stack chính sau đây:



Hơn nữa, bằng cách chọn các dịch vụ SaaS, tôi sẽ tiết kiệm thời gian hơn nữa vì tôi sẽ không cần phải tự mình triển khai các tính năng này. Các dịch vụ tôi quyết định như sau.



Đây là những công nghệ chính mà tôi phải học càng nhanh càng tốt để bắt đầu thực hiện dự án. Mọi thứ khác sẽ phải được học trong suốt quá trình.


Tại thời điểm này, tôi bắt đầu tìm hiểu các công nghệ mới. Đối với những điều chính và quan trọng nhất, tôi bắt đầu đọc những cuốn sách sau.



Tôi quyết định sẽ làm công việc toàn thời gian của mình vào ban ngày nhưng buổi tối là một trò chơi công bằng. Khi tôi về nhà, tôi có thể học cho đến khi tôi đi ngủ. Theo thời gian của giấc ngủ, tôi sẽ giảm xuống còn 6 giờ để có thêm thời gian học.


Tôi dự đoán ban đầu tôi sẽ chỉ cần một năm để xây dựng dự án này. Sau đó, sau gần một năm tìm hiểu các công nghệ mới, đã đến tháng 12 năm 2018 và tôi vừa hoàn thành tài liệu đọc chính, trong khi viết đúng 0 dòng mã.

Sự phát triển bắt đầu

Vào tháng 12 năm 2018, tôi cuối cùng đã bắt đầu phát triển. Tôi thiết lập Visual Studio Code và bắt đầu xây dựng môi trường phát triển của mình.


Tôi đã rõ ràng từ ngày đầu tiên rằng tôi sẽ không thể duy trì tất cả các máy chủ cần thiết cho một dự án lớn như vậy. Không chỉ từ góc độ kỹ thuật, mà cả từ khía cạnh ngân sách. Vì vậy, tôi đã phải tìm một giải pháp.


May mắn thay, tôi đã tìm thấy giải pháp dưới dạng DevOps và cách tiếp cận Serverless cho cơ sở hạ tầng back-end.


Tôi thấy rõ ngay lập tức, ngay cả trước khi những cách tiếp cận này trở nên phổ biến như ngày nay, rằng nếu chúng ta có thể mô tả điều gì đó ngắn gọn bằng mã, chúng ta cũng có thể tự động hóa nó, do đó, tiết kiệm thời gian và tài nguyên.


Với DevOps, tôi sẽ thống nhất và tự động hóa cả quá trình phát triển front-end và back-end, trong khi với Serverless, tôi sẽ loại bỏ nhu cầu bảo trì máy chủ và giảm chi phí vận hành.


Triết lý này rõ ràng đã đi theo dòng suy nghĩ của tôi và điều đầu tiên tôi quyết định thiết lập là một đường ống CI / CD với Terraform.


Thiết kế bao gồm 3 nhánh, Phát triển, UAT và Sản xuất. Tôi sẽ làm việc mỗi ngày và khi công việc hoàn thành, tôi chỉ cần cam kết các thay đổi đối với nhánh Phát triển trong AWS CodeCommit và điều này sẽ kích hoạt AWS CodeBuild xây dựng dự án của tôi.


Tôi sẽ giữ một bản thực thi Terraform trong kho lưu trữ, cho cả macOS, cho thử nghiệm cục bộ và một bản dựa trên Linux, cho các bản dựng trên CodeBuild.


Khi quá trình xây dựng bắt đầu, tệp thực thi Terraform sẽ được gọi bên trong CodeBuild và nó sẽ nhận các tệp mã Terraform, do đó xây dựng cơ sở hạ tầng của tôi trên AWS.


Tất cả các phần này sau đó sẽ phải được kết nối và tự động, mà tôi đã thực hiện bằng cách sử dụngAWS CodePipeline, sẽ chuyển mã từ CodeCommit sang CodeBuild mỗi khi tôi thực hiện cam kết.


Điều này sẽ giúp tôi giữ cho mã và cơ sở hạ tầng của tôi được đồng bộ hóa. Bất cứ khi nào tôi sẵn sàng tiến lên, tôi chỉ cần hợp nhất nhánh Phát triển với UAT hoặc UAT với Sản xuất để đồng bộ hóa các môi trường khác của tôi.

2019 - COVID-19 lượt truy cập

Sau khi tôi hoàn thành đường ống CI / CD cho giao diện người dùng, tôi sẽ chuyển sang thiết lập trang web thực tế cục bộ để bắt đầu phát triển giao diện người dùng.


Bước đầu tiên của việc thiết lập giao diện người dùng là tạo một dự án dựa trên Aurelia. Quyết định đằng sau việc sử dụng Aurelia chứ không phải React, vốn đã và vẫn là lựa chọn phổ biến nhất cho khung JavaScript, là do mẫu MVVM .


Mẫu MVVM được sử dụng nổi bật trong các ứng dụng WPF dành cho máy tính để bàn mà tôi đã có kinh nghiệm. Vì vậy, việc học React sẽ mất nhiều thời gian hơn là chỉ đơn giản là xây dựng dựa trên những gì tôi đã biết.


Mặt khác, quyết định sử dụng Aurelia chứ không phải Angular hay Vue dựa trên triết lý đằng sau Aurelia đó là - để khung làm việc theo cách của bạn. Nói cách khác, không có Aurelia ở Aurelia.


Về cơ bản, những gì bạn đang sử dụng, trong khi phát triển với Aurelia là HTML, JavaScript và CSS, với một số tính năng bổ sung như liên kết dữ liệu với các thuộc tính mà tôi đã quen thuộc.


Do đó, quyết định là cuối cùng. Tiếp theo, đến từ thế giới C # được nhập tĩnh, tôi quyết định sử dụng TypeScript thay vì JavaScript.


Tiếp theo là WebPack. Rõ ràng là cần phải chia ứng dụng thành nhiều phần để tạo điều kiện tải chậm. Vì tôi đã biết rằng sẽ có nhiều tính năng trong ứng dụng, nên bắt buộc phải xây dựng nó như một SPA có thể tải các bộ phận theo yêu cầu.


Nếu không, trải nghiệm người dùng sẽ không thể chấp nhận được.


Để giúp xử lý cấu hình WebPack dễ dàng hơn, tôi quyết định thêm Neutrino.JS vào hỗn hợp và sử dụng giao diện thông thạo của nó để thiết lập WebPack.


Ai cũng biết rằng duyệt web trên thiết bị di động đã gia tăng kể cả vào năm 2019. Để sẵn sàng cho web hiện đại, cách tiếp cận phát triển đã được xác định như sau.



Điều này được hỗ trợ bởi hai công nghệ chính - Tailwind CSS và PWA. Khi nói đến kiểu dáng, để đơn giản hóa hệ thống hơn nữa, tôi đã thêm Tailwind CSS, đây hóa ra là một trong những quyết định tốt nhất mà tôi đưa ra, vì nó ưu tiên thiết bị di động theo mặc định.


Ngoài ra, nó dựa trên tiện ích, do đó nó có khả năng tái sử dụng cao, đó chính xác là những gì tôi đang tìm kiếm.


Hơn nữa, vì tôi đang cố gắng cung cấp trải nghiệm giống như bản gốc, nhưng không có thời gian để xây dựng các ứng dụng gốc, nên tôi quyết định hướng tới điều tốt nhất tiếp theo - một ứng dụng có thể được cài đặt trực tiếp từ trình duyệt và hoạt động ngoại tuyến.


Đây là những gì Ứng dụng web tiến bộ (PWA) muốn cung cấp cho người dùng, nhưng thiết lập thủ công sẽ quá dễ xảy ra lỗi và tốn thời gian, do đó tôi quyết định sử dụng Google WorkBox có cài đặt Service Worker, ngoại tuyến và các tính năng lưu vào bộ nhớ đệm được xây dựng trong.


Khi phần lõi đã được thiết lập, đã đến lúc đưa nó lên mạng. Rõ ràng rằng trang web phải luôn có thể truy cập được cho mọi người, sự cố không thuộc về một hệ thống hiện đại, vì vậy tôi quyết định thiết lập hệ thống theo cách sau.


Thứ nhất, các tệp HTML và JS sẽ được phân phát từ nhóm AWS S3. Để cung cấp cho nó với độ trễ thấp trên toàn cầu, nó sẽ được hỗ trợ bởi AWS CloudFront CDN Network.


Trong trường hợp này, có một chút thất bại là khi tôi quyết định sử dụng Serverless Framework vì việc thiết lập các chức năng AWS Lambda dễ dàng hơn so với Terraform, do đó tôi đã giới thiệu một công nghệ mới mà tôi phải quan tâm.


Sau khi thiết lập xong, tôi đã mua các miền trong AWS Route 53, miền mà tôi đã sử dụng để thử nghiệm và miền sản xuất - https://immersive.community .


Ý tưởng đằng sau cái tên này đến từ một mạng dựa trên cộng đồng có tên tương tự - Mighty Networks . Tôi chỉ đơn giản quyết định chọn từ “Chìm đắm” vì vào thời điểm đó, từ này bắt đầu có xu hướng cao trên Google.


Vì đã sử dụng “các công cụ“ đắm chìm ”và“ các cộng đồng đắm chìm ”, nên tôi đã quyết định sử dụng“ công cụ nhập vai ”.


Bây giờ tôi đã khởi chạy giao diện người dùng, đã đến lúc bắt đầu làm việc trên cơ sở dữ liệu. Mặc dù trước đây tôi đã quen với cơ sở dữ liệu quan hệ, dựa trên SQL, chúng rõ ràng là quá chậm đối với dự án cụ thể này, vì vậy tôi quyết định sử dụng cơ sở dữ liệu NoSQL. Tôi đã chọn AWS DynamoDB vì cung cấp Serverless của nó.


Để truy cập cơ sở dữ liệu, tôi đã chọn AWS AppSync, là một triển khai GraphQL được quản lý và cũng không có máy chủ.

Hệ thống nhiều người thuê

Tại thời điểm này, đã đến lúc bắt đầu giải quyết một trong những vấn đề lớn nhất mà tôi phải đối mặt, đó là:


Làm thế nào để cho phép người dùng tham gia nhiều cộng đồng nhưng giữ cho dữ liệu riêng tư hoặc bị hạn chế, trong mỗi cộng đồng, tách biệt với nhau?


Cách dễ nhất để giải quyết vấn đề này là tạo nhiều cơ sở dữ liệu, nhưng điều này có những hạn chế rõ ràng bởi vì, vào một thời điểm nào đó, chúng ta sẽ hết cơ sở dữ liệu mà chúng ta có thể tạo.


Hóa ra là mỗi tài khoản AWS có giới hạn về số lượng tài nguyên bạn có thể tạo, vì vậy đây không phải là một giải pháp khả thi.


Sau đó, cuối cùng tôi sẽ giải quyết vấn đề này bằng cách gán một cột kiểu cho mỗi mục nhập trong cơ sở dữ liệu DynamoDB. Mỗi người dùng sẽ có loại của nó được đặt thành “người dùng”, trong khi mỗi cộng đồng sẽ đơn giản được đặt là “web”.


Sau đó, tôi sẽ chỉ ra rằng một người dùng đã tham gia cộng đồng bằng cách thêm một hàng mới trong đó khóa của hàng này được chỉ định là „user # web_user # web“. Vì người dùng và tên cộng đồng sẽ là duy nhất, khóa này cũng sẽ là duy nhất, vì vậy người dùng không thể tham gia cộng đồng nhiều lần.


Nếu tôi muốn thực hiện một hành động chỉ có thể được thực hiện nếu người dùng đã tham gia cộng đồng, tôi chỉ cần sử dụng Hàm đường ống do AppSync cung cấp cho phép bạn truy vấn nhiều hàng trong DynamoDB.


Sau đó, tôi sẽ truy vấn và kiểm tra xem người dùng có phải là thành viên của cộng đồng hay không và chỉ khi có, hãy cho phép người dùng thực hiện hành động.


Điều này đã giải quyết được vấn đề nhiều người thuê nhà , nhưng một trong những vấn đề lớn nhất cần giải quyết mới chỉ là vấn đề nan giải.

Kiến trúc khả dụng cao

Không cần phải nói rằng một hệ thống cấp doanh nghiệp được xây dựng với khả năng chịu lỗi và tính sẵn sàng cao. Điều này sẽ cho phép người dùng tiếp tục sử dụng hệ thống, ngay cả khi có lỗi trong một số thành phần của nó.


Nếu chúng ta muốn triển khai một hệ thống như vậy, chúng ta nên làm điều đó với sự dự phòng trong tâm trí.


Nghiên cứu của tôi đã đưa tôi đến giải pháp tối ưu trong trường hợp này, đó là kiến trúc Khả dụng cao Hoạt động tích cực . Nó chỉ ra rằng hầu hết các dịch vụ trên AWS đã có sẵn rất nhiều, nhưng bản thân AppSync thì không. Vì vậy, tôi quyết định tạo triển khai của riêng mình.


Trang web không đưa ra giải pháp cho vấn đề này, vì vậy tôi phải tự xây dựng. Tôi bắt đầu suy nghĩ trên toàn cầu. Có nghĩa là, khách truy cập của tôi sẽ đến từ các khu vực khác nhau và nếu tôi đặt AppSync của mình ở Hoa Kỳ, thì khách truy cập ở châu Á sẽ có độ trễ cao hơn.


Tôi đã giải quyết vấn đề độ trễ và tính khả dụng cao theo cách sau. Tôi đã quyết định tạo 10 API AppSync khác nhau ở tất cả các khu vực có sẵn tại thời điểm đó. Hiện tại, các API được đặt ở Hoa Kỳ, Châu Á và Châu Âu.


Hơn nữa, mỗi API cần được kết nối với cơ sở dữ liệu DynamoDB tương ứng, nằm trong cùng một vùng. Do đó, tôi đã tạo thêm 10 bảng DynamoDB bổ sung.


May mắn thay, DynamoDB cung cấp tính năng Bảng toàn cầu sao chép dữ liệu giữa các bảng DynamoDB được kết nối và đồng bộ hóa chúng.


Giờ đây, bất kể người dùng ghi vào cơ sở dữ liệu ở đâu, người dùng ở một khu vực khác sẽ có thể đọc cùng một thông tin đó, sau khi dữ liệu được đồng bộ hóa.


Câu hỏi bây giờ nảy sinh là như sau.


Người dùng sẽ được chuyển đến API gần nhất như thế nào? Không chỉ vậy, nếu trong trường hợp một API bị lỗi, chúng ta sẽ lập tức định tuyến lệnh gọi đến API có sẵn tiếp theo như thế nào?


Giải pháp ra đời dưới dạng các hàm CloudFront và Lambda @ Edge . Đó là một tính năng tuyệt vời của CloudFront có thể kích hoạt các chức năng Lambda @ Edge trong khu vực có người gọi.


Cần phải nói rõ rằng nếu chúng ta biết vị trí của người dùng, chúng ta có thể chọn API, bên trong hàm Lambda @ Edge, dựa trên nơi cuộc gọi đến.


Hơn nữa, chúng ta cũng có thể lấy vùng của hàm Lambda @ Edge đang thực thi, do đó, cho phép chúng ta chọn API AppSync trong cùng vùng đó. Bước đầu tiên để triển khai giải pháp này là ủy quyền các cuộc gọi AppSync thông qua CloudFront.


Do đó, bây giờ, các cuộc gọi sẽ được thực hiện trực tiếp đến CloudFront thay vì AppSync.


Sau đó, tôi phải trích xuất lệnh gọi HTTP từ các tham số CloudFront bên trong hàm Lambda @ Edge. Sau khi tôi có vùng và truy vấn AppSync, được trích xuất từ các tham số CloudFront, tôi sẽ thực hiện một lệnh gọi HTTP mới tới API AppSync tương ứng.


Khi dữ liệu trả về, tôi chỉ cần chuyển nó trở lại CloudFront thông qua chức năng Lambda @ Edge. Sau đó, người dùng sẽ nhận được dữ liệu được yêu cầu.


Nhưng chúng tôi vẫn chưa giải quyết được yêu cầu Active-Active. Mục tiêu bây giờ là phát hiện điểm khi một API không khả dụng và sau đó chuyển sang một API khác. Tôi đã giải quyết vấn đề này bằng cách kiểm tra kết quả của cuộc gọi AppSync. Nếu đó không phải là phản hồi HTTP 200, cuộc gọi rõ ràng không thành công.

Sau đó, tôi chỉ cần chọn một khu vực khác từ danh sách tất cả các khu vực có sẵn và sau đó thực hiện cuộc gọi tới API AppSync tiếp theo trong khu vực đó. Nếu cuộc gọi thành công, chúng tôi trả về kết quả, và nếu nó không thành công, chúng tôi thử vùng tiếp theo cho đến khi thành công.


Nếu vùng cuối cùng cũng không thành công, thì chúng tôi chỉ trả về kết quả không thành công.


Đây chỉ đơn giản là triển khai Round Robin của kiến trúc Khả dụng cao Hoạt động. Với hệ thống này hiện tại, chúng tôi đã thực sự triển khai ba tính năng sau:


  • Độ trễ thấp toàn cầu
  • Cân bằng tải dựa trên khu vực
  • Tính sẵn sàng cao Active-Active


Rõ ràng chúng tôi có độ trễ trung bình thấp đối với mỗi người dùng toàn cầu, vì mỗi người dùng sẽ được chuyển đến khu vực gần nhất mà họ đang thực hiện lệnh gọi tới API. Chúng tôi cũng có tính năng cân bằng tải dựa trên khu vực, vì người dùng sẽ được chuyển đến nhiều API trong khu vực của họ.


Cuối cùng, chúng tôi có Tính khả dụng cao đang hoạt động, vì hệ thống sẽ vẫn hoạt động ngay cả khi một số API hoặc cơ sở dữ liệu của nó bị lỗi vì người dùng sẽ được chuyển đến API có sẵn tiếp theo.


Nó thực sự sẽ không đủ để chỉ đơn giản xử lý tính khả dụng cao cho các API. Tôi muốn có nó cho tất cả các tài nguyên, bao gồm các tệp HTML và JavaScript được cung cấp từ CloudFront.


Lần này, tôi đã sử dụng phương pháp tương tự nhưng đã tạo 16 nhóm AWS S3. Mỗi nhóm sẽ phân phát các tệp giống nhau, nhưng sẽ nằm ở các vùng khác nhau.


Trong trường hợp này, khi người dùng truy cập trang web của chúng tôi, trình duyệt sẽ thực hiện nhiều lệnh gọi HTTP tới các tệp HTML, JS, JSON hoặc hình ảnh. Trong trường hợp này, Lambda @ Edge sẽ phải trích xuất URL hiện đang được gọi.


Khi tôi đã có URL, tôi sẽ phải xác định loại tệp của tệp này và thực hiện một cuộc gọi HTTP mới đến nhóm S3 tương ứng trong khu vực.


Không cần phải nói, nếu cuộc gọi thành công, chúng tôi sẽ trả lại tệp, trong khi nếu nó không thành công, chúng tôi sẽ sử dụng cùng một hệ thống định tuyến như trước đây, do đó cũng cung cấp một hệ thống Khả dụng Hoạt động Cao.


Với hệ thống này hiện đã được áp dụng, chúng tôi đã đạt được một cột mốc quan trọng khác và đặt một nền tảng khác cho cơ sở hạ tầng cấp doanh nghiệp của chúng tôi. Đây là hệ thống khó phát triển nhất và mất 3 tháng để hoàn thành.


Hóa ra, chúng tôi có nhiều vấn đề cần giải quyết hơn và hệ thống này sẽ trở lại hữu ích.

Tệp kê khai PWA động

PWA là một công nghệ web tuyệt vời và sẽ được nhiều trang web sử dụng hơn khi thời gian trôi qua, nhưng trở lại năm 2019, mọi thứ chỉ mới bắt đầu.


Vì tôi quyết định phục vụ từng cộng đồng trên một miền phụ riêng biệt, nên tôi cũng muốn cung cấp cho người dùng khả năng cài đặt PWA mang thương hiệu của họ, với tiêu đề và biểu tượng ứng dụng thích hợp.

Hóa ra, tệp PWA Manifest, định nghĩa tất cả các tính năng này, không hoạt động dựa trên các miền phụ. Nó chỉ có thể xác định một bộ giá trị dựa trên miền mà nó được phân phát.


Thực tế là tôi đã có thể ủy quyền các cuộc gọi HTTP bằng CloudFront và Lambda @ Edge cũng rất hữu ích ở đây.


Mục tiêu bây giờ là ủy quyền cho mỗi cuộc gọi đến tệp manifest.json. Sau đó, tùy thuộc vào tên miền phụ mà cuộc gọi đến từ, để nhận dữ liệu cộng đồng tương ứng, đó sẽ là biểu tượng ứng dụng, tiêu đề, v.v., sau đó chúng tôi sẽ tự động điền vào tệp kê khai.json với các giá trị này.

Sau đó, tệp sẽ được cung cấp cho trình duyệt và cộng đồng sau đó sẽ được cài đặt dưới dạng một ứng dụng PWA mới trên thiết bị của người dùng.

Di chuyển đến Giao diện người dùng

Khi tôi đã tìm ra các bước quan trọng này, đã đến lúc bắt đầu làm việc với giao diện người dùng. Theo yêu cầu dựa trên miền phụ trước đây, chúng tôi cũng phải tìm ra cách tải một cộng đồng khác và dữ liệu của cộng đồng đó dựa trên miền phụ.


Điều này cũng sẽ yêu cầu tải các bố cục trang web khác nhau, sẽ được sử dụng trong mỗi cộng đồng.


Ví dụ: trang chủ sẽ cần liệt kê tất cả các cộng đồng có sẵn, trong khi các tên miền phụ khác sẽ cần liệt kê các bài viết trên mỗi cộng đồng đó.


Không cần phải nói rằng để giải quyết vấn đề này, chúng ta không thể chỉ xây dựng nhiều trang web khác nhau từ đầu. Điều này sẽ không mở rộng quy mô, vì vậy thay vào đó, chúng tôi sẽ cần sử dụng lại nhiều điều khiển và tính năng nhất có thể.


Các tính năng này sẽ được chia sẻ giữa hai loại cộng đồng này và sau đó sẽ chỉ được tải nếu chúng được yêu cầu. Để tối đa hóa khả năng tái sử dụng của mã, tôi đã định nghĩa tất cả các điều khiển là 4 loại khác nhau.


  • Các thành phần
  • Kiểm soát
  • Các trang
  • Cộng đồng


Các phần tử HTML tùy chỉnh nhỏ nhất như <button> và <input> được định nghĩa là Thành phần. Sau đó, chúng tôi có thể sử dụng lại các Thành phần này trong Điều khiển là tập hợp các phần tử nhỏ hơn này, ví dụ: Điều khiển thông tin hồ sơ sẽ hiển thị hình ảnh hồ sơ của người dùng, tên người dùng, người theo dõi, v.v.


Sau đó, chúng tôi sẽ có thể sử dụng lại các phần tử này trong các phần tử cấp cao hơn, trong trường hợp của chúng tôi là - Trang.


Mỗi trang về cơ bản sẽ đại diện cho một lộ trình, ví dụ: trang Xu hướng, nơi chúng ta có thể xem tất cả các hoạt động hoặc trang Sở thích nơi văn bản bài viết thực tế sẽ được hiển thị. Sau đó, tôi sẽ soạn từng Trang từ các Điều khiển nhỏ hơn này.


Cuối cùng, các phần tử cấp cao nhất sẽ được xác định trong Cộng đồng, dựa trên loại của chúng. Sau đó, mỗi phần tử Cộng đồng sẽ chỉ cần xác định tất cả các Trang cấp thấp hơn mà nó yêu cầu.


Bộ định tuyến Aurelia rất hữu ích trong trường hợp này là cách bạn có thể tải các tuyến đường một cách động. Việc thực hiện được xử lý theo cách sau.


Bất kể tên miền phụ nào, khi trang web bắt đầu tải, chúng tôi đăng ký hai nhánh chính, được triển khai dưới dạng các thành phần Aurelia. Chúng đại diện cho hai loại cộng đồng khác nhau. Sau đó, tôi xác định hai loại hoặc bố cục web khác nhau:


  • Chính
  • Bài báo


Loại "chính" chỉ đại diện cho bố cục trang web sẽ được tải khi người dùng truy cập vào trang https://immersive.community chính. Tại đây, chúng tôi sẽ hiển thị tất cả các cộng đồng với tất cả các điều khiển tương ứng.

Mặt khác, khi người dùng điều hướng đến tên miền phụ, chúng tôi sẽ cần tải một bố cục khác. Nói cách khác, thay vì cộng đồng, chúng tôi sẽ tải các bài báo và các tính năng và lộ trình tương ứng, chẳng hạn như khả năng xuất bản và chỉnh sửa các bài báo.


Điều này có thể bật hoặc tắt một số tuyến đường nhất định, dựa trên loại cộng đồng mà chúng tôi có mặt.


Thiết lập Aurelia và WebPack của chúng tôi chia JavaScript thành các phần thích hợp để các tuyến đường và tính năng không cần thiết sẽ không bị tải, do đó cải thiện tốc độ và tiết kiệm băng thông.

Tại thời điểm này, khi chúng tôi xác định được tên miền phụ mà chúng tôi đang đặt, chúng tôi sẽ tải cộng đồng và dữ liệu người dùng cho cộng đồng cụ thể này, do đó đã triển khai thành công giải pháp.

Bố cục Masonry

Đó là lý do của tôi rằng chúng tôi nên cố gắng giữ cho thiết kế càng đơn giản càng tốt. Vì vậy, vì người dùng đến trang web để tìm nội dung, chúng tôi sẽ tập trung vào việc hiển thị nội dung, thay vì các tính năng phụ.


Các bài báo sẽ cần được hiển thị trong danh sách, nhưng chúng không được trông cũ, vì vậy tôi quyết định rằng mỗi bài viết sẽ chỉ đơn giản bao gồm những điều sau đây.


  • Ảnh bìa
  • Tiêu đề bài viết
  • Hạng mục bài viết
  • Ngày bài báo được đăng hoặc chỉnh sửa
  • Hồ sơ của tác giả


Cách chính mà tôi đảm bảo rằng danh sách các bài báo sẽ không bị cũ, đó là đảm bảo người dùng có thể chọn tỷ lệ co của mỗi ảnh bìa cho bài viết của họ. Nguồn cảm hứng đến từ cách hiển thị các ghim của Pinterest, vì vậy mỗi bài viết cũng sẽ có một tỷ lệ khung hình khác nhau.


Điều này yêu cầu tôi phải triển khai bố cục khối xây, không thể chọn ngoài hộp trong CSS Grid hoặc FlexBox.

May mắn thay, có một số triển khai mã nguồn mở hữu ích mà tôi đã thử và sử dụng cho bố cục. Tôi đã phải thêm một số cải tiến, như tải dữ liệu được phân trang và chia tỷ lệ với kích thước màn hình.


Và sau đó…


Vào tháng 11 năm 2019, những dấu hiệu đầu tiên của COVID-19 bắt đầu xuất hiện. Thế giới nhanh chóng rơi vào tình trạng hỗn loạn và không ai có manh mối điều gì đang xảy ra, nhưng nó sẽ thay đổi thế giới và cách chúng ta tương tác với nhau theo những cách mà không ai có thể tưởng tượng được.

Ngay sau đó, chúng tôi sẽ bắt đầu làm việc tại nhà. Điều này sẽ có tác động lớn đến quá trình phát triển của tôi vì tôi không phải đi làm nữa. Trớ trêu thay, thế giới sụp đổ, trong khi tôi có được kỳ nghỉ mà tôi cần!

Sở thích và đánh giá

Quay trở lại thế giới phát triển, ý tưởng đằng sau việc viết bài trên Cộng đồng nhập vai dựa trên sự hợp tác. Để đạt được điều này, tôi đã sử dụng Wikipedia như một cơ sở cho nỗ lực hợp tác.


Ngoài ra, các trang web cộng đồng như Amino AppsFandom.com và trang web viết blog HubPages.com cũng đóng vai trò của họ.


Viết các bài đăng trên blog với tư cách một người có thể là một khởi đầu tốt, nhưng chúng ta có thể vượt qua điều đó bằng cách để mọi người viết bài cùng nhau.


Khi chúng tôi thêm các siêu liên kết vào văn bản và kết nối các bài báo này được viết bởi những người khác nhau, về cơ bản chúng tôi tạo ra một cộng đồng nơi mọi người đến với nhau để tham gia vào các chủ đề mà họ quan tâm.


Tôi đã quyết định xác định hai loại bài báo, cụ thể là,


  • Sở thích
  • Nhận xét


Sở thích sẽ là những bài báo ngắn, ước chừng. Các bài báo dài 5000 ký tự sẽ mô tả thực tế bất kỳ sở thích cụ thể nào mà một người có thể có. Sau đó, mỗi người có thể viết đánh giá, với xếp hạng về mối quan tâm cụ thể này.


Sau đó, trang quan tâm chính sẽ tổ chức tham chiếu đến tất cả các bài đánh giá được viết cho mối quan tâm cụ thể này. Sự khác biệt chính là bất kỳ ai cũng có thể chỉnh sửa Sở thích, nhưng chỉ người tác giả Bài đánh giá mới có thể chỉnh sửa nó, do đó tạo thêm dấu ấn cá nhân cho mỗi bài viết.


Ở đây, quyết định trước đó của chúng tôi về việc sử dụng CloudFront để ủy quyền các cuộc gọi AppSync đã trở lại khiến chúng tôi khó chịu. Nó chỉ ra rằng CloudFront chỉ hỗ trợ độ dài chuỗi truy vấn lên đến 8.192 byte , do đó, chúng tôi không thể lưu dữ liệu dài hơn thế.


Đối với mỗi bài viết đi, mỗi sở thích có thể được thích và bình luận. Vì vậy, những người sử dụng có thể đến với nhau và thảo luận về cách mỗi bài báo sẽ được viết và chỉnh sửa. Hơn nữa, mỗi Sở thích có thể được thêm vào trang hồ sơ của người dùng, để truy cập nhanh.


Khi tất cả các tính năng này đã có, cuối năm đã đến. Tình hình có vẻ khả quan và tôi chắc chắn dự án sẽ hoàn thành vào năm sau. Ít nhất thì giả định này không chính xác.

2020 - Tốc độ tối đa phía trước

Năm nay ít nhiều đã khởi đầu tốt đẹp. Nền kinh tế vẫn được duy trì phần nào nhưng sau một thời gian, bắt đầu đi xuống. Các thị trường bắt đầu phản ứng với đại dịch và tương tự như vậy, giá bắt đầu tăng.


Đầu năm 2020 là năm mà tôi đã làm rất nhiều việc nhưng không có một sản phẩm thực sự hoạt động. Vẫn còn rất nhiều việc phải làm, nhưng tôi tin tưởng vào kết quả, vì vậy tôi tiếp tục đẩy mạnh về phía trước.


Ở công việc ban ngày của tôi, giờ làm việc cũng bị kéo dài và chúng tôi phải hoàn thành thời hạn nhanh hơn bình thường. Không cần phải nói rằng tôi phải sắp xếp lại lịch trình của mình và cách duy nhất để tiết kiệm thời gian hơn là chỉ ngủ 4 tiếng mỗi đêm.


Ý tưởng là trở về nhà trước 6 hoặc 7 giờ tối và sau đó bắt đầu làm việc với dự án. Sau đó tôi có thể làm việc đến 3 hoặc 4 giờ sáng và sau đó đi ngủ. Sau đó, tôi sẽ phải thức dậy vào khoảng 7 giờ sáng và nhanh chóng bắt đầu công việc trong ngày của mình.


Tất nhiên, điều này sẽ không phải là ngủ đủ mỗi đêm, nhưng tôi nghĩ rằng tôi sẽ bù đắp khoảng thời gian đó bằng cách ngủ 12 tiếng trong những ngày cuối tuần. Tôi cũng đã lên lịch cho tất cả các ngày nghỉ phép và các ngày nghỉ lễ cho công việc.


Hệ thống mới đã được thiết lập và tôi đã tiến hành theo kế hoạch.

Trình chỉnh sửa Markdown

Không cần phải nói rằng một trang web viết bài phải có một trình soạn thảo văn bản dễ sử dụng. Vào đầu năm 2020, Markdown nổi lên như một cách rất phổ biến để viết văn bản. Tôi quyết định rằng Cộng đồng nhập vai sẽ phải hỗ trợ nó ngay từ đầu.


Điều này không chỉ yêu cầu tôi viết Markdown mà còn hiển thị nó dưới dạng HTML. Thư viện Markdown-It sẽ được sử dụng để chuyển Markdown thành HTML. Nhưng có một yêu cầu bổ sung, vì vậy danh sách đầy đủ các phương tiện khác nhau mà chúng tôi sẽ hiển thị như sau.


  • Chữ
  • Hình ảnh
  • Video
  • Nhúng


Hơn nữa, hình ảnh và video sẽ được hiển thị dưới dạng thanh trượt, nơi người dùng có thể vuốt hình ảnh như trên Instagram. Điều này sẽ yêu cầu kết hợp Markdown và các phần tử HTML khác.


Trình chỉnh sửa sẽ được chia thành nhiều phần trong đó có hai loại đầu vào, trường văn bản và trường phương tiện. Mỗi trường trong trình chỉnh sửa có thể được di chuyển lên hoặc xuống, điều này khá dễ thực hiện bằng cách sử dụng Sortable.js .


Khi nói đến các trường đầu vào, trường Markdown đủ đơn giản để tạo với phần tử <textareosystem. Trình chỉnh sửa cũng tải Phông chữ Google Inconsolata để cung cấp cho văn bản, văn bản đang được nhập, giao diện của máy đánh chữ.

Hơn nữa, để thực sự tạo kiểu cho văn bản, một thanh đã được triển khai để thêm Markdown vào văn bản. Điều tương tự cũng được thực hiện bằng các phím tắt bằng Mousetrap.js . Giờ đây, chúng ta có thể dễ dàng thêm văn bản in đậm dưới dạng thẻ ** Markdown bằng Control + B, v.v.


Trong khi nhập, việc phần tử <textareosystem mở rộng khi lượng văn bản tăng lên là điều hoàn toàn tự nhiên, vì vậy tôi đã sử dụng thư viện Autosize.js để triển khai tính năng này.


Trường phương tiện sẽ có thể hiển thị hình ảnh, video hoặc iframe chứa các trang web được nhúng. Loại trường phương tiện sẽ chuyển đổi dựa trên chính loại phương tiện. Tôi đã sử dụng Swiper.js để thực hiện thao tác vuốt giữa các hình ảnh.


Thành phần video được triển khai bằng thư viện Video.js .


Các vấn đề bắt đầu phát sinh khi đến lúc thực sự tải lên các phương tiện truyền thông. Về hình ảnh, thật dễ dàng sử dụng API tệp của trình duyệt để tải ảnh và video từ thiết bị của bạn. Sau đó, những gì tôi phải làm, trước tiên là chuyển đổi hình ảnh, có thể có định dạng HEIC thành JPEG.


Sau đó, tôi sẽ nén chúng lại, trước khi tải chúng lên back end. May mắn thay, các thư viện Heic-ConvertBrowser-Image-Compression đã phục vụ tốt mục đích này.


Một vấn đề khác xảy ra khi tôi phải chọn tỷ lệ khung hình ảnh chính xác và cắt nó trước khi tải lên. Điều này đã được thực hiện bằng Cropper.JS nhưng không may, không hoạt động tốt trên trình duyệt Safari.


Tôi đã dành khá nhiều thời gian để thiết lập CSS thích hợp để hình ảnh không bị tràn khỏi vùng chứa. Cuối cùng, người dùng có thể dễ dàng tải hình ảnh từ thiết bị của mình, phóng to và thu nhỏ, và cũng có thể cắt hình ảnh trước khi tải lên.


Khi mọi thứ đã hoàn tất, phương tiện sẽ được tải lên Cloudinary, một dịch vụ để quản lý các tệp phương tiện.


Sau đó, đã đến lúc kết hợp tất cả những điều này lại với nhau và hiển thị nó cho người dùng dưới dạng các bài báo. Tôi đủ may mắn rằng Aurelia có một phần tử <compose> có thể tải HTML động.


Do đó, tùy thuộc vào kiểu đầu vào, tôi sẽ tải phần tử media hoặc phần tử Markdown, phần tử này sẽ được chuyển thành HTML.


HTML này sau đó sẽ phải được tạo kiểu bằng CSS, đặc biệt là các bảng HTML mà tôi sẽ biến đổi tùy thuộc vào kích thước màn hình. Trên màn hình lớn hơn, các bảng sẽ được hiển thị theo bố cục ngang thông thường, trong khi trên màn hình nhỏ hơn, chúng sẽ được hiển thị theo bố cục dọc.


Điều này sẽ yêu cầu cách tiếp cận theo hướng sự kiện sẽ cho chúng tôi biết khi nào và kích thước màn hình thay đổi như thế nào. Thư viện tốt nhất để sử dụng trong trường hợp này là RxJs , xử lý các sự kiện "thay đổi kích thước" và tôi có thể định dạng bảng cho phù hợp.

Cải thiện đầu vào dữ liệu

Sau đó tôi quay lại các bài báo. Tôi đã phải thay đổi cách các bài báo được lưu vào cơ sở dữ liệu vì trường hợp nhiều người có thể sửa đổi bài báo cùng một lúc.


Sau đó, tôi sẽ lưu bài viết mới dưới dạng một loại bài viết ban đầu, nhưng dữ liệu thực tế của mỗi bài viết sẽ được lưu dưới dạng một phiên bản. Sau đó, tôi sẽ có thể theo dõi người dùng nào và khi nào mỗi bài viết được thay đổi.


Điều này cho phép tôi ngăn phiên bản mới được lưu nếu người dùng không tải phiên bản mới nhất trước. Ngoài ra, nếu một bản cập nhật nào đó không phù hợp, nó có thể bị vô hiệu hóa và phiên bản trước đó sẽ hiển thị lại. Bản nháp cho mỗi bài báo sẽ được lưu theo cùng một cách.


Theo như dữ liệu đầu vào thực tế, tôi quyết định triển khai nó dưới dạng cửa sổ bật lên. Bản thân cửa sổ bật lên sẽ không chỉ xuất hiện trên màn hình mà sẽ trượt lên từ phía dưới. Hơn nữa, có thể vuốt vào bên trong cửa sổ bật lên.


Với mục đích này, tôi đã sử dụng lại thư viện Swiper.Js, trong khi tất cả các hoạt ảnh khác được thực hiện bằng thư viện Animate.CSS .


Cửa sổ bật lên không đơn giản để thực hiện vì nó yêu cầu phải chia tỷ lệ với kích thước màn hình. Do đó, trên màn hình lớn hơn, nó sẽ chiếm 50% chiều rộng màn hình trong khi trên màn hình nhỏ hơn sẽ chiếm 100% chiều rộng.


Hơn nữa, trong một số trường hợp nhất định, như với danh sách những người theo dõi, tôi đã triển khai cuộn được chứa trong cửa sổ bật lên. Điều này có nghĩa là danh sách mà chúng tôi đang cuộn không dừng lại ở trên cùng mà sẽ biến mất khi cuộn.


Tôi cũng đã thêm kiểu dáng khác và làm mờ nền và tắt cuộn hoặc nhấp bên ngoài cửa sổ bật lên. Mặt khác, cửa sổ bật lên Xem trước cho hệ thống chỉnh sửa bài viết di chuyển cùng với màn hình.


Điều này được lấy cảm hứng từ ứng dụng Phím tắt của Apple và cách cửa sổ bật lên của nó xuất hiện, cũng dành cho các nút và tiêu đề máy tính bảng phía trên các phần tử.

Thanh điều hướng

Một trong những tính năng giao diện người dùng quan trọng nhất mà tôi đã triển khai được lấy cảm hứng từ iPhone, đó là thanh điều hướng của nó. Tôi nhận thấy rằng hầu hết các ứng dụng dành cho thiết bị di động đều có một thanh điều hướng khá cơ bản, với các biểu tượng đơn giản và nhỏ không thực sự phù hợp với thiết kế tổng thể của ứng dụng.


Tôi đã quyết định chỉ cần sao chép thanh iOS và sử dụng nó trên toàn bộ trang web. Không cần phải nói, nó không phải lúc nào cũng hiển thị mà thay vào đó sẽ biến mất khi chúng ta cuộn xuống và xuất hiện khi chúng ta cuộn lên.


Khi người dùng cuộn xuống, chúng tôi cho rằng anh ta quan tâm đến nội dung và sẽ không điều hướng khỏi trang hiện tại, do đó chúng tôi có thể ẩn thanh này.


Mặt khác, nếu người dùng đang cuộn lên, họ có thể đang tìm cách rời khỏi trang, vì vậy chúng tôi cũng có thể hiển thị lại thanh.


Có bốn nút trên thanh và chúng cho phép người dùng điều hướng đến bốn phần chính của trang web. Nút Trang chủ điều hướng đến trang chủ của mỗi cộng đồng. Nút Xu hướng điều hướng đến trang Xu hướng nơi người dùng có thể xem tất cả các hoạt động gần đây mà người dùng khác đã đăng.


Nút tiếp theo là nút Tương tác điều hướng đến danh sách tất cả các tính năng và cài đặt mà cộng đồng cung cấp. Cuối cùng, nút Hồ sơ dẫn chúng ta đến trang hồ sơ của mình.


Cũng cần phải tính đến màn hình lớn hơn, vì vậy thanh thực sự di chuyển sang phía bên phải của màn hình khi hiển thị trên màn hình lớn. Nó trở nên dính và không di chuyển bất cứ nơi nào tại thời điểm đó.

Xử lý hàng loạt theo thời gian thực

Khi công việc quan trọng nhất của giao diện người dùng đã được hoàn thành, đây là lúc bạn nên ghé thăm giao diện người dùng một lần nữa. Phần này của hệ thống sẽ được chứng minh là một trong những phần phức tạp nhất để triển khai nhưng cuối cùng, rất quan trọng và cũng sẽ giúp bạn khá dễ dàng tiến hành các tính năng khác.


Trong Lập trình hướng đối tượng , tồn tại một khái niệm về Tách các mối quan tâm , nơi chúng ta giữ cho các chức năng của mình đơn giản và khiến chúng chỉ làm một việc duy nhất mà chúng phải làm.


Hơn nữa, ý tưởng của Lập trình Định hướng Theo khía cạnh đặc biệt về sự tách biệt các mối quan tâm, nơi chúng ta cần tách logic kinh doanh khỏi các mối quan tâm xuyên suốt khác.


Ví dụ, lưu người dùng vào cơ sở dữ liệu đương nhiên phải đi kèm với ghi nhật ký, trong khi việc lưu người dùng đang được xử lý. Nhưng mã cho hai tính năng này nên được giữ riêng biệt.


Tôi đã quyết định áp dụng lý luận này trên diện rộng và trích xuất càng nhiều tính năng từ giao diện người dùng, những tính năng không quan trọng đối với người dùng và chuyển chúng vào phần cuối.


Trong trường hợp của chúng tôi, chúng tôi chủ yếu quan tâm đến việc lưu dữ liệu vào cơ sở dữ liệu, liên quan đến cộng đồng, bài báo, nhận xét, lượt thích, v.v.


Nếu chúng tôi muốn theo dõi số lượt thích một bài viết, chúng tôi có thể có một quy trình đếm tất cả số lượt thích cho mỗi bài viết và cập nhật chúng theo định kỳ.


Vì chúng tôi ở đây xử lý một lượng lớn dữ liệu được lưu trữ trong cơ sở dữ liệu và có khả năng là một lượng lớn dữ liệu liên tục được chuyển đến cơ sở dữ liệu, chúng tôi sẽ cần sử dụng xử lý dữ liệu thời gian thực để xử lý tình huống này.

Tôi đã chọn AWS Kinesis cho nhiệm vụ này. Kinesis có thể nhập một lượng lớn dữ liệu thời gian thực và chúng tôi cũng có thể viết các truy vấn SQL để truy vấn và xử lý hàng loạt dữ liệu này trong thời gian gần thực. Theo mặc định, Kinesis sẽ xử lý hàng loạt dữ liệu trong 60 giây hoặc hàng loạt đạt 5 MB, tùy điều kiện nào đến trước.


Vì vậy, trong trường hợp của chúng tôi, chúng tôi sẽ truy vấn dữ liệu đến, ý nghĩa, việc tạo cộng đồng mới, thêm hoặc xóa các bài báo, người dùng, hoạt động, v.v. và cập nhật cơ sở dữ liệu mỗi phút với dữ liệu mới. Câu hỏi đặt ra bây giờ là làm cách nào để chúng ta lấy dữ liệu vào Kinesis ngay từ đầu?


Cơ sở dữ liệu lựa chọn của chúng tôi, DynamoDB thực sự có thể xác định các trình kích hoạt được gọi, dưới dạng các hàm Lambda, bất cứ khi nào dữ liệu được thêm, xóa hoặc sửa đổi. Sau đó, chúng tôi sẽ nắm bắt dữ liệu này và gửi cho Kinesis để xử lý.


Nó chỉ xảy ra như vậy, rằng một trong những quyết định trước đó của chúng tôi sẽ khiến quá trình này khó thực hiện hơn một chút vì chúng tôi không xử lý 1 cơ sở dữ liệu, mà thực sự đang xử lý 10 cơ sở dữ liệu.


Do đó, khi dữ liệu được thêm vào, các hàm Lambda sẽ được gọi 10 lần thay vì một lần, tuy nhiên chúng ta cần xử lý từng trường hợp vì dữ liệu có thể đến từ bất kỳ cơ sở dữ liệu nào vì chúng nằm ở các vùng khác nhau.


Tôi đã giải quyết vấn đề này bằng cách lọc ra dữ liệu được sao chép trái ngược với dữ liệu gốc được người dùng thêm vào cơ sở dữ liệu.


Cột “aws: rep: updateregion” cung cấp cho chúng tôi thông tin này và chúng tôi có thể xác định xem chúng tôi đang xử lý dữ liệu trong khu vực nơi nó được chèn vào hay nó đại diện cho dữ liệu được sao chép.


Khi vấn đề này đã được giải quyết, chúng tôi sẽ chỉ lọc, bổ sung dữ liệu mới hoặc xóa dữ liệu đó. Hơn nữa, chúng tôi sẽ lọc dữ liệu dựa trên loại của nó, có nghĩa là chúng tôi đang xử lý dữ liệu đại diện cho một cộng đồng, bài viết, nhận xét, v.v.


Sau đó, chúng tôi thu thập dữ liệu này, đánh dấu là “CHÈN” hoặc “XÓA” và chuyển cho Kinesis. Những ý tưởng này từ phương pháp Thiết kế theo hướng miền được gọi là Sự kiện miền và cho phép chúng tôi xác định hành động nào đã xảy ra và cập nhật cơ sở dữ liệu của chúng tôi cho phù hợp.




Sau đó, chúng tôi chuyển sự chú ý sang Kinesis. Ở đây, chúng tôi phải xác định ba phần chính của hệ thống


  • Luồng dữ liệu AWS Kinesis
  • AWS Kinesis Firehose
  • Phân tích dữ liệu AWS Kinesis


Kinesis Streams cho phép chúng tôi nhập dữ liệu theo thời gian thực với số lượng lớn. Kinesis Analytics là một hệ thống cho phép chúng tôi thực sự truy vấn dữ liệu này theo lô và tổng hợp dựa trên khoảng thời gian luân phiên.


Sau khi dữ liệu được tổng hợp, chúng tôi sẽ đẩy từng kết quả vào Kinesis Firehose, công cụ này có thể xử lý lượng lớn dữ liệu và lưu trữ nó trong một dịch vụ đích, trong trường hợp của chúng tôi, là một nhóm S3 ở định dạng JSON.


Khi dữ liệu đến nhóm S3, chúng tôi kích hoạt một hàm Lambda khác và xử lý dữ liệu này để cập nhật cơ sở dữ liệu DynamoDB.


Ví dụ: nếu 5 người thích một Sở thích trong phút trước, chúng tôi sẽ tìm thấy dữ liệu này trong tệp JSON của mình. Sau đó, chúng tôi sẽ cập nhật số lượng tương tự cho Sở thích này và tăng hoặc giảm số lượng tương tự. Trong trường hợp này, chúng tôi chỉ cần tăng nó cho 5 lượt thích.


Sử dụng hệ thống này, số liệu thống kê của mọi cộng đồng sẽ được cập nhật trong vòng một phút.


Hơn nữa, chúng tôi sẽ không cần phải viết và thực hiện các truy vấn phức tạp khi chúng tôi cần hiển thị dữ liệu tổng hợp, vì kết quả chính xác được lưu trữ trong cơ sở dữ liệu DynamoDB nhanh chóng trong mỗi bản ghi, do đó tăng tốc độ truy vấn cho mỗi bản ghi.


Cải tiến này dựa trên ý tưởng về địa phương dữ liệu

Đám mây

Bây giờ đã đến lúc bắt đầu triển khai các dịch vụ của bên thứ 3, dịch vụ này sẽ xử lý các tính năng mà tôi cần phải có nhưng dễ dàng mua đăng ký hơn là tự xây dựng. Dịch vụ đầu tiên tôi triển khai là Cloudinary, là một dịch vụ quản lý phương tiện.


Tôi đã thiết lập tất cả các cài đặt trước trên Cloudinary để háo hức chuyển đổi hình ảnh cho các điểm ngắt màn hình đáp ứng sau đây.


  • 576 pixel
  • 768 pixel
  • 992 pixel
  • 1200 px


Đây cũng sẽ là các điểm ngắt được đặt trong Tailwind CSS nơi trang web của chúng tôi sẽ tuân theo các kích thước màn hình khác nhau cho điện thoại di động, máy tính bảng nhỏ, máy tính bảng lớn và màn hình máy tính.


Sau đó, tùy thuộc vào kích thước màn hình hiện tại, chúng tôi sẽ gọi các hình ảnh được tạo háo hức từ Cloudinary một cách thích hợp bằng cách sử dụng thuộc tính scrcset trên phần tử <image>.


Điều này sẽ giúp chúng tôi tiết kiệm băng thông và rút ngắn thời gian tải hình ảnh trên thiết bị di động.


Về phía tính năng video, sau khi nó được triển khai, tôi đã quyết định bỏ nó vì giá cho các video tại Cloudinary quá đắt. Vì vậy, mặc dù có mã ở đó, tính năng này hiện không được sử dụng nhưng có thể khả dụng sau này.


Điều này sẽ yêu cầu tôi xây dựng một hệ thống tùy chỉnh trên AWS trong tương lai.

Embed.ly

Tôi quyết định sử dụng Embed.ly để nhúng nội dung từ các trang web phổ biến như Twitter, YouTube, v.v.


Thật không may, điều này không hoạt động mà không có vấn đề, vì vậy tôi phải sử dụng một số kỹ thuật để xóa các tập lệnh Facebook và Twitter khỏi trang web theo cách thủ công vì chúng sẽ can thiệp vào nội dung được nhúng sau khi nó được tải nhiều lần.

Algolia

Khi nói đến tìm kiếm, tôi đã chọn Algolia và triển khai tìm kiếm cộng đồng, hoạt động, bài báo và người dùng. Việc triển khai front-end đủ đơn giản.


Tôi chỉ cần tạo một thanh tìm kiếm, khi được nhấp vào, sẽ ẩn phần còn lại của ứng dụng và trong khi chúng tôi nhập, sẽ hiển thị kết quả cho miền phụ cụ thể mà chúng tôi hiện đang duyệt.


Khi chúng tôi nhấn “Enter”, khối xây trên trang chủ sẽ hiển thị các bài viết phù hợp với truy vấn. Không cần phải nói rằng tôi cũng phải thực hiện phân trang sẽ tải kết quả tăng dần, để bắt chước giao diện của Pinterest.


Vấn đề xảy ra khi tôi nhận ra rằng không có cách nào để thực sự tìm kiếm các hoạt động trừ khi bạn lưu trữ toàn bộ văn bản trong Algolia, điều mà tôi muốn tránh. Do đó, tôi quyết định chỉ lưu trữ các thẻ có liên quan cho mỗi hoạt động, nhưng câu hỏi đặt ra là làm thế nào để trích xuất các thẻ có liên quan từ mỗi hoạt động.


Câu trả lời đến dưới dạng AWS DịchAWS Toàn diện . Vì số lượng mục sẽ được thêm vào cơ sở dữ liệu sẽ lớn và chúng tôi muốn thêm dữ liệu này vào Algolia, chúng tôi có thể làm quá tải API nếu chúng tôi thêm từng bản ghi riêng biệt.


Thay vào đó, chúng tôi muốn xử lý chúng theo thời gian thực và theo lô, do đó, chúng tôi lại sử dụng Kinesis như một giải pháp.


Trong trường hợp này, mỗi lần bổ sung một mục mới vào cơ sở dữ liệu sẽ kích hoạt một hàm Lambda sẽ gửi dữ liệu đó đến Kinesis Data Streams, sau đó sẽ gửi dữ liệu đến Kinesis Firehose (không cần Analytics lần này) và lưu trữ thêm trong một thùng S3.


Khi dữ liệu được lưu trữ an toàn, chúng tôi sẽ kích hoạt một hàm Lambda sẽ gửi nó đến Algolia, nhưng trước đó, chúng tôi cần xử lý dữ liệu này.


Đặc biệt, chúng tôi sẽ cần xử lý các hoạt động, từ đó chúng tôi sẽ loại bỏ văn bản Markdown bằng cách sử dụng thư viện xóa đánh dấu. Sau đó, chúng tôi sẽ được để lại với bản rõ. Khi chúng tôi có văn bản thực tế, chúng tôi có thể tiến hành trích xuất các thẻ có liên quan sẽ được sử dụng cho việc tìm kiếm.


Điều này có thể dễ dàng thực hiện bằng cách sử dụng dịch vụ Toàn diện AWS, nhưng vấn đề là nó chỉ hỗ trợ một số ngôn ngữ. Do đó, nếu người dùng đang viết bằng ngôn ngữ không được hỗ trợ, chúng tôi sẽ không thể trích xuất các thẻ.


Trong trường hợp này, chúng tôi chỉ cần sử dụng AWS Dịch và dịch văn bản sang tiếng Anh. Sau đó, chúng tôi tiến hành giải nén các thẻ và sau đó chúng tôi dịch chúng trở lại ngôn ngữ gốc.


Bây giờ, chúng tôi chỉ cần lưu trữ các thẻ trong Algolia như dự định.

Recombee

Một trong những tính năng quan trọng nhất mà Pinterest có là công cụ đề xuất của nó. Sau khi người dùng nhấp vào một Ghim, anh ta sẽ ngay lập tức hiển thị hình ảnh kích thước đầy đủ của Ghim, trong khi bên dưới hình ảnh, chúng ta có thể thấy các đề xuất mà người dùng có thể thích, dựa trên Ghim hiện tại.


Đây là một cách rất tốt để tăng tỷ lệ giữ chân người dùng và khiến họ tiếp tục duyệt trang web. Để triển khai tính năng này, trong trường hợp của tôi sẽ phải hiển thị các bài báo tương tự cho người dùng, tôi đã chọn Recombee - là một công cụ đề xuất SaaS.


Việc triển khai lần này dễ dàng hơn so với Algolia vì tôi sử dụng lại các nguyên tắc tương tự. Vì chúng tôi sẽ cần giới thiệu cộng đồng, bài viết và hoạt động như thế nào đối với mỗi mục mới do người dùng tạo, tôi sẽ sử dụng Kinesis để gộp các mục này và gửi chúng đến Recombee.


Quy trình đề xuất dựa trên Chế độ xem, nghĩa là mỗi khi người dùng xem một bài viết, chúng tôi sẽ gửi Chế độ xem cho người dùng cụ thể này và bài viết tới Recombee.


Chúng tôi cũng có thể chỉ định các hành động khác cho các mục trong Recombee, dựa trên cách người dùng tương tác với chúng. Ví dụ: việc viết một Sở thích mới sẽ được ánh xạ tới một Bổ sung giỏ hàng cho Sở thích đó. Nếu người dùng thích một Sở thích, đây sẽ là một bổ sung cho Xếp hạng.


Nếu người dùng tham gia cộng đồng, điều này sẽ được ánh xạ tới Dấu trang cho cộng đồng này.


Dựa trên dữ liệu này, Recombee sẽ tạo các đề xuất cho người dùng.


Ở giao diện người dùng, tôi chỉ cần lấy bài báo mà người dùng hiện đang đọc và lấy dữ liệu đề xuất cho bài viết cụ thể này và người dùng. Điều này sẽ được hiển thị ở cuối mỗi bài viết, dưới dạng danh sách khối xây được phân trang.


Điều này sẽ cung cấp cho người dùng một danh sách các bài báo tiềm năng mà họ có thể muốn đọc.

Locize

Nhìn thấy cách trang web sẽ hướng đến khán giả toàn cầu ngay từ đầu, tôi cũng phải thực hiện bản địa hóa. Đối với bản phát hành đầu tiên, tôi quyết định sử dụng 10 ngôn ngữ và sử dụng dịch vụ SaaS - Locize, được triển khai dựa trên khung bản địa hóa i18next .


Chúng tôi sẽ cần bản địa hóa các từ dựa trên số lượng, nghĩa là số ít hoặc số nhiều, và cũng sẽ phải bản địa hóa thời gian. Xem như cách chúng tôi hiển thị thời gian mỗi bài viết được tạo hoặc cập nhật lần cuối.


Tôi đã chọn tiếng Anh làm ngôn ngữ mặc định và dịch tất cả các từ bằng Google Dịch sang các ngôn ngữ khác như tiếng Đức, tiếng Nhật, v.v. Một lần nữa rất tiện lợi là Aurelia cũng hỗ trợ bản địa hóa.


Sau khi hoàn tất tất cả các bản dịch, tôi đã nhập các tệp JSON đã dịch vào ứng dụng và tách chúng ra dựa trên loại cộng đồng, để chúng tôi không tải văn bản không cần thiết sẽ không được sử dụng.


Aurelia sau đó cho phép chúng tôi chỉ cần sử dụng các mẫu và liên kết sẽ tự động dịch văn bản. Nhưng tôi cũng sử dụng Công cụ chuyển đổi giá trị sẽ định dạng thời gian, để hiển thị thời gian đã trôi qua kể từ khi một bài báo được viết, trái ngược với việc hiển thị ngày tháng thực tế.


Hơn nữa, tôi cũng phải định dạng các số, do đó thay vì hiển thị số 1000, tôi sẽ hiển thị 1K. Tất cả các tính năng này đã được xử lý bởi các thư viện như NumbroTimeAgo .

Twilio

Một trang web cộng đồng yêu cầu giao tiếp, nhưng không chỉ ở nơi công cộng. Nó cũng yêu cầu giao tiếp riêng tư. Điều này có nghĩa là một cuộc trò chuyện riêng tư trong thời gian thực cũng phải là thứ mà tôi cần cung cấp. Tính năng này được triển khai bằng cách sử dụng dịch vụ Trò chuyện có thể lập trình Twilio.


Mọi người dùng có thể trò chuyện riêng tư với bất kỳ người dùng nào khác trong từng cộng đồng cụ thể. Việc triển khai back-end đủ dễ dàng để thực hiện bằng cách sử dụng các thư viện Twilio. Khi nói đến giao diện người dùng, tôi quyết định tạo kiểu trò chuyện dựa trên Instagram vì nó có thiết kế đơn giản và gọn gàng.

Kết xuất trước SPA

Tôi cũng đã chọn một dịch vụ có tên là Prerender để sử dụng để kết xuất trước trang web nhằm cung cấp cho các trình thu thập thông tin của công cụ tìm kiếm. Sau khi nhận ra giá cả có thể là một vấn đề đáng lo ngại, tôi đã quyết định thực sự tự mình xây dựng hệ thống kết xuất trước.


Cuối cùng, tôi đã tìm thấy một thư viện có tên Puppeteer , là một API Chrome không đầu.


Thư viện này có thể được sử dụng để tải các trang web theo chương trình và trả về HTML được tạo với JavaScript được thực thi, điều mà các trình thu thập thông tin tìm kiếm vào thời điểm đó không làm được. Việc triển khai sẽ tải Puppeteer trong một hàm Lambda, hàm này sẽ tải một trang web, hiển thị nó và trả về HTML.


Tôi sẽ sử dụng Lambda @ Edge để phát hiện khi nào người dùng của tôi thực sự là một trình thu thập thông tin và sau đó chuyển nó cho Lambda kết xuất trước. Điều này đủ đơn giản để thực hiện bằng cách phát hiện thuộc tính "tác nhân người dùng" trong các tham số CloudFront. Hóa ra là Lambda không thể tải thư viện Puppeteer vì nó quá lớn.


Đây không phải là trình dừng vì sau đó tôi đã tìm thấy thư viện chrome-aws-lambda , thư viện này đã thực hiện tất cả công việc này ngay lập tức và sẽ nhỏ hơn nhiều vì nó chỉ sử dụng lõi Puppeteer, cần thiết cho mục đích của tôi.


Khi hệ thống được hoàn thành, các công cụ tìm kiếm đã đủ mạnh và cũng bắt đầu thực thi JavaScript. Vì vậy, ngay cả khi tôi đã hoàn thành tính năng này, tôi đã tắt nó đi và tôi chỉ cho phép các công cụ tìm kiếm tự thu thập dữ liệu trang web của tôi.

Vạch sọc

Một trong những tính năng cốt lõi của Cộng đồng đắm chìm là chương trình Chia sẻ doanh thu, trong đó người dùng chia sẻ 50% đăng ký thành viên và doanh thu quảng cáo.


Như đã nêu trước đây, chúng tôi cần cho phép người sáng tạo không chỉ tạo nội dung của họ mà còn kiếm tiền từ nội dung đó. Câu hỏi bây giờ là làm thế nào để triển khai hệ thống này. Không cần phải nói rằng lựa chọn mặc định là Stripe, vì vậy tôi đã tiến hành như sau.


Tôi đã quyết định thiết kế hệ thống Chia sẻ Doanh thu dựa trên từng cộng đồng. Bằng cách này, người dùng có thể tạo một số cộng đồng và kiếm tiền dựa trên mỗi cộng đồng. Doanh thu cho mỗi cộng đồng sẽ đến từ hai nguồn.


  • Đăng ký thành viên
  • Quảng cáo tự phục vụ


Đăng ký thành viên là dễ dàng nhất để thực hiện. Tôi sẽ tạo ba mức giá cho đăng ký thành viên, $ 5, $ 10 và $ 15 hàng tháng. Các thành viên của mỗi cộng đồng sau đó có thể hỗ trợ chủ sở hữu của cộng đồng hàng tháng và đổi lại, sẽ không được hiển thị bất kỳ quảng cáo nào.


Hệ thống quảng cáo dựa trên các đăng ký hàng tháng giống nhau nhưng sẽ dao động trong khoảng từ $ 100 đến $ 1000 hàng tháng. Công ty muốn quảng cáo trong một cộng đồng cụ thể có thể chỉ cần chọn số tiền thanh toán hàng tháng và đặt biểu ngữ quảng cáo.


Giả sử có một số nhà quảng cáo trong một cộng đồng, các quảng cáo sẽ được chọn ngẫu nhiên với mỗi lần tải trang hoặc thay đổi lộ trình. Cách nhà quảng cáo có thể tăng tần suất hiển thị quảng cáo của họ so với các nhà quảng cáo khác bằng cách tăng số tiền thanh toán hàng tháng.


Chúng tôi cũng cần cho nhà quảng cáo biết quảng cáo của họ đang hoạt động như thế nào, vì vậy tôi lại sử dụng thiết lập Kinesis để đo lường cả lượt xem và lượt nhấp. Hệ thống này sau đó sẽ cập nhật số liệu thống kê như bình thường và sau đó tôi sử dụng thư viện Brite Charts để hiển thị số liệu thống kê.


Phần quan trọng nhất là tính năng chia sẻ doanh thu thực tế. Điều này được thực hiện đơn giản bởi tính năng Stripe Connect . Người dùng chỉ cần thêm tài khoản ngân hàng của họ và kết nối với Stripe Express và hệ thống sau đó sẽ có tất cả thông tin cần thiết để gửi thanh toán.



Sau đó, tôi sẽ có một hệ thống Lambda được lên lịch để thu thập tất cả người dùng hàng ngày và cập nhật các giao dịch và đảm bảo rằng 50% của mỗi giao dịch (đăng ký thành viên hoặc thanh toán quảng cáo) được chuyển cho chủ sở hữu của cộng đồng nơi thanh toán. thực hiện.

AWS Cognito

Dịch vụ cuối cùng phải được triển khai là Auth0 , sẽ giúp xác thực người dùng. Sau một số nghiên cứu, tôi đã quyết định thiết lập không cần mật khẩu, dựa trên tin nhắn SMS.


Nhìn thấy chúng ta đang ở trong thế giới ưu tiên di động như thế nào, việc bỏ mật khẩu và xác thực dựa trên thứ mà mọi người đã có - điện thoại di động của họ chỉ có ý nghĩa.


Hóa ra việc triển khai xác thực không mật khẩu của Auth0 là không tối ưu vì nó sẽ chuyển hướng đến trang web của họ mọi lúc và sẽ dựa trên các tham số URL, điều mà tôi muốn tránh.


Việc định giá cũng sẽ không quy mô cho một thứ gì đó như mạng xã hội, vì vậy tôi quyết định xây dựng triển khai của riêng mình bằng cách sử dụng AWS Cognito.


Khá thuận tiện là Cognito có các trình kích hoạt có thể được kết nối với các chức năng Lambda, đây là những gì tôi đã sử dụng để kích hoạt xác thực. Các hàm Lambda sẽ được sử dụng để thu thập dữ liệu người dùng trong quá trình đăng ký.


Tại thời điểm này, người dùng chỉ cần cung cấp số điện thoại và tên người dùng của mình để đăng ký.

Trong quá trình đăng nhập, chức năng Lambda sẽ thu thập số điện thoại của người dùng và gửi tin nhắn SMS, chứa mã xác minh cho người dùng, sử dụng AWS SNS .


Sau đó, người dùng sẽ chỉ cần nhập mã này để được xác minh thông qua Cognito và sẽ được chuyển hướng đến trang hồ sơ của anh ấy.


Tất nhiên, khi người dùng được ủy quyền và nhận được dữ liệu xác thực được chuyển trở lại giao diện người dùng, chúng tôi sẽ phải mã hóa nó trước khi có thể lưu trữ. Dữ liệu ủy quyền tương tự sẽ được mã hóa trước khi được lưu trữ ở mặt sau.


Ngoài ra, trong mỗi lần đăng ký và đăng nhập, chúng tôi lưu trữ IP của người dùng.


Sau đó, hóa ra người dùng thực sự gặp vấn đề với việc cung cấp số điện thoại di động của họ, vì vậy tôi quyết định thay thế SMS bằng tin nhắn email.


Đã xảy ra sự cố với các tin nhắn trùng lặp khi tôi muốn sử dụng AWS SES , vì vậy tôi đã chuyển sang SendGrid của Twilio để gửi email cho người dùng.


Với hệ thống này đã hoàn thành, năm đó đã hết và dự án mà tôi bắt đầu cách đây 2 năm vẫn chưa hoàn thành. Không còn sự lựa chọn nào khác ngoài việc tiếp tục làm việc và cố gắng hoàn thành nó càng sớm càng tốt. Tôi ít biết rằng những thách thức lớn nhất vẫn chưa đến.

2021 - Không có kết thúc trong tầm nhìn

Đây là lúc mọi thứ phải đi vào đúng vị trí, nhưng làm việc với tư cách là một nhà phát triển solo mà không có bất kỳ phản hồi nào trong thời gian dài khiến bạn đặt câu hỏi về hướng đi của dự án.


Câu hỏi mà bất kỳ nhà phát triển nào hiện đang ở cùng một vị trí ngay bây giờ có thể tự hỏi mình câu hỏi sau.


Làm thế nào tôi có thể giữ cho mình động lực và có thể tiếp tục đi, mặc dù tôi không thấy điểm cuối trong tầm mắt?


Câu trả lời khá đơn giản.


Đơn giản là bạn không nên đặt câu hỏi về quyết định của mình, bất kể cảm giác hiện tại của bạn về dự án như thế nào. Bạn không thể cho phép, trạng thái cảm xúc hiện tại của bạn, xác định cách bạn sẽ hành động.


Bạn có thể không muốn tiếp tục ngay bây giờ, nhưng bạn có thể cảm thấy thích nó sau này và bạn chắc chắn sẽ cảm thấy tồi tệ nếu bạn thực sự bỏ thuốc lá.


Vì vậy, nếu bạn bỏ cuộc, bạn sẽ không có dự án nữa và tất cả công việc sẽ chẳng là gì cả. Vì vậy, điều duy nhất cần làm là tiếp tục tiến về phía trước, bất kể điều gì xảy ra.


Điều duy nhất cần ghi nhớ tại thời điểm này là mọi tính năng được cung cấp, mọi thao tác nhấn bàn phím đều giúp bạn tiến gần hơn đến mục tiêu.


Trong thời gian thực hiện dự án này, tôi thực sự đã thay đổi công việc 3 lần, mỗi lần đều khá liên quan, nhưng dù phải đi phỏng vấn xin việc, tôi vẫn quay về nhà, ngồi sau bàn và tiếp tục làm việc với dự án của mình.


Những điều bạn phải tự hỏi bản thân, nếu bạn đang thiếu động lực, là những điều sau đây.


Nếu bây giờ bạn bỏ việc, bạn sẽ đi đâu? Cách duy nhất bạn có thể đi, sau khi bỏ thuốc lá, là trở lại nơi bạn xuất phát. Nhưng bạn đã biết những gì ở đó. Bạn đã biết nó như thế nào, và bạn không thích nó, đó là lý do tại sao bạn bắt đầu cuộc hành trình này ngay từ đầu. Vì vậy, bây giờ bạn biết một thực tế, rằng không có nơi nào để quay trở lại. Con đường duy nhất bạn có thể đi là về phía trước. Và cách duy nhất để tiến lên, là tiếp tục làm việc.


Đây là tất cả động lực mà tôi có được trong suốt dự án này, như tôi đã nói rồi, đó là hoặc quay trở lại nơi tôi đã có, vì vậy tôi quyết định tiếp tục tiến về phía trước.

Hệ thống quản trị

Bây giờ đã đến lúc bắt đầu tập hợp mọi thứ lại với nhau và để bắt đầu, tôi quyết định triển khai Hệ thống quản trị viên sẽ được sử dụng để duy trì mỗi cộng đồng. Mỗi chủ sở hữu cộng đồng sẽ có thể đưa ra quyết định về việc xóa nội dung trong cộng đồng của họ.


Điều này ngụ ý rằng chúng tôi có thể vô hiệu hóa quảng cáo, bài viết và hoạt động và cấm người dùng nếu hành động của họ không phù hợp với các quy tắc ứng xử.


Chủ sở hữu của mỗi cộng đồng cũng có thể cấp quyền quản trị viên cho những người dùng khác. Nhưng chúng tôi cũng cần tạo điều kiện cho quản trị viên trên cộng đồng chính có thể quản lý tất cả các cộng đồng khác.


Hơn nữa, những quản trị viên này có thể vô hiệu hóa hoàn toàn những người dùng khác khỏi tất cả các cộng đồng và thậm chí vô hiệu hóa toàn bộ cộng đồng.


Để giúp quản trị viên thực hiện công việc của họ dễ dàng hơn, tôi đã giới thiệu hệ thống gắn cờ, nơi mỗi mục có thể được báo cáo cho quản trị viên. Người dùng hiện có thể báo cáo bất kỳ điều gì trên trang web mà họ cho là không phù hợp.


Việc xác nhận thực tế các quyền cho mỗi người dùng sẽ được quyết định ở phía sau. Tôi chỉ cần tạo một hàm Lambda sẽ được gọi bên trong mỗi lệnh gọi AppSync, hàm này sẽ xác thực từng yêu cầu.


Hơn nữa, giao diện người dùng sẽ sử dụng ủy quyền dựa trên định tuyến được cung cấp bởi Aurelia. Tôi chỉ đơn giản là xác định các quy tắc sẽ cho phép hoặc không cho phép người dùng hiện tại tiếp tục đến một tuyến đường nhất định.


Ví dụ: bạn sẽ không thể xem hồ sơ của mình nếu bạn đã bị cấm tham gia một cộng đồng nhất định. Nhưng hệ thống này cũng có thể được sử dụng để ngăn ai đó điều hướng đến trang hồ sơ nếu họ chưa đăng nhập, thay vào đó, họ sẽ được chuyển hướng đến trang đăng nhập.

Trang tổng quan phân tích

Một tính năng khác sẽ hữu ích cho người dùng là trang Bảng điều khiển Analytics. Mỗi chủ sở hữu cộng đồng có thể xem các biểu đồ hiển thị chính xác mức độ tương tác đang diễn ra trong cộng đồng của mình.


Đối với trường hợp cụ thể này, tôi sẽ sử dụng lại dữ liệu được Kinesis tổng hợp và hiển thị nó với các biểu đồ bằng thư viện Brite Charts .


Hơn nữa, tôi cũng sẽ lấy dữ liệu Stripe và hiển thị số lượng người đăng ký, nhà quảng cáo và tổng thu nhập mà cộng đồng này có.


Vấn đề duy nhất phải giải quyết là thiết kế đáp ứng, nghĩa là làm thế nào để hiển thị biểu đồ trên cả màn hình nhỏ và lớn. Một lần nữa, tôi đã sử dụng RxJs để phát hiện sự kiện "thay đổi kích thước" và áp dụng kiểu dựa trên các điểm ngắt màn hình được xác định trong Tailwind CSS.

Bảo vệ

Một mức độ bảo mật bổ sung cũng đã được đưa vào lộ trình và tôi quyết định triển khai WAF trước các bản phân phối CloudFront của mình.


Tôi đã sử dụng AWS Marketplace và đăng ký hệ thống Imperva WAF sẽ ủy quyền cho lưu lượng truy cập của tôi và đảm bảo chỉ cho phép lưu lượng đã được xác thực là an toàn.


Giải pháp khá dễ thực hiện, Nhưng khi hết tháng đầu tiên, hóa đơn quá nhiều để xử lý nên tôi đã ngắt kết nối hệ thống và quyết định chỉ dựa vào những gì CloudFront cung cấp theo mặc định.

Phút cuối thiết kế lại

Tại thời điểm này, tôi phải bắt đầu xem xét tất cả những gì tôi đã làm và bắt đầu sửa chữa những vấn đề nhỏ còn sót lại. Nhiều thứ cần phải được đánh bóng, nhưng điều lớn nhất phải thay đổi là thiết lập cơ sở dữ liệu DynamoDB.


Nó chỉ ra rằng thiết lập ban đầu của tôi, không phải là thiết lập mà tôi đang sử dụng bây giờ, sẽ không mở rộng quy mô tốt. Đây là lý do tại sao tôi quyết định thiết kế lại hoàn toàn nó và bắt đầu sử dụng dấu phân tách „#“ để chỉ ra sự phân nhánh trong mã định danh của bản ghi.


Trước đây, tôi đã tạo các bản ghi riêng biệt và sử dụng Đường ống AppSync để xác định từng bản ghi có liên quan, điều này rõ ràng là không bền vững. Điều này cũng ảnh hưởng đến việc thiết lập Kinesis và các dịch vụ của bên thứ 3 như Algolia và Recombee.


Đổi lại, phải mất 3 tháng để thiết kế lại hoàn toàn hệ thống hoạt động bình thường. Sau khi điều này được thực hiện, tôi có thể tiếp tục với các tính năng mới một lần nữa.

Mùa hè hấp dẫn nhất được ghi lại

Mùa hè ở Tokyo nóng và ẩm ướt. Đó là một thách thức khá lớn để giữ vững quan điểm với bất cứ điều gì bạn đang làm, đặc biệt là vào tháng Bảy và tháng Tám.


Trong thời gian đó, Thế vận hội đang được tổ chức tại Tokyo, và vào ngày 7 tháng 8, có thông tin cho rằng nhiệt độ nóng nhất được ghi nhận trong lịch sử Thế vận hội .


Không cần phải nói, đi làm bằng tàu hỏa sẽ không còn ý nghĩa nữa vì thời tiết sẽ quá mệt mỏi, khiến tôi kiệt sức và không thể làm việc vào buổi tối. Tôi nhận ra rằng thay vào đó tôi phải tiết kiệm thời gian hơn bằng cách đi taxi đến nơi làm việc.


Điều này giúp tôi có thêm thời gian để ngủ và sẽ giúp tôi không quá mệt mỏi để làm việc sau khi trở về nhà.

Thông báo thời gian thực

PWA là một công nghệ tuyệt vời và nó cung cấp cho chúng tôi một cách để gửi thông báo cho người dùng bằng cách sử dụng Thông báo đẩy. Tôi quyết định rằng đây sẽ là một hệ thống cũng sẽ cần thiết và tiến hành triển khai.


Hệ thống thông báo sẽ được triển khai dựa trên người dùng đang bị theo dõi. Nếu bạn đang theo dõi một người dùng, thì khi anh ta tạo một hoạt động mới hoặc một bài báo, bạn sẽ cần được thông báo.


Hiện tại, vấn đề duy nhất với Thông báo đẩy là tại thời điểm viết bài này, chúng vẫn chưa được trình duyệt Safari trên thiết bị iOS hỗ trợ. Thay vì Thông báo đẩy gốc, tôi đã quyết định sử dụng API Thông báo của trình duyệt.


Mặt sau, tôi sẽ tạo một phiên bản mới của AWS API Gateway và thiết lập nó hoạt động với dữ liệu thời gian thực.


Ở giao diện người dùng, tôi sẽ tạo kết nối bằng API WebSocket với Cổng API. Sau khi người dùng đang được theo dõi, xuất bản một bài viết mới, dữ liệu này sẽ được gửi đến Kinesis. Một lần nữa, bằng cách sử dụng xử lý hàng loạt, chúng tôi nhận được tất cả những người dùng theo dõi tác giả và sau đó, sử dụng API Gateway để gửi thông báo đến giao diện người dùng.


Ở giao diện người dùng, kết nối WebSocket được kích hoạt, đến lượt chúng tôi sử dụng để gọi API thông báo của trình duyệt và hiển thị thông báo.


Hơn nữa, khi nói đến các nhận xét mà người dùng có thể viết trên mỗi bài viết, chúng tôi cần theo dõi và hiển thị cho người dùng biết nơi anh ta đang tham gia vào các cuộc thảo luận.


Tôi cũng đã triển khai một chỉ báo chưa đọc sẽ hiển thị phần bình luận nào có nhận xét mới mà người dùng vẫn chưa đọc.


Điều này sẽ được kiểm tra khi người dùng tải ứng dụng mà không sử dụng từ khóa await khi thực hiện lệnh gọi AppSync. Điều này sẽ đảm bảo rằng quá trình thực thi không đợi cuộc gọi hoàn tất mà thay vào đó, dữ liệu quan trọng hơn sẽ được tải trước.


Sau khi cuộc gọi quay lại, chúng tôi chỉ cần cập nhật giao diện người dùng và hiển thị thông báo cho người dùng.

Tôi cũng sẽ sử dụng các thông báo dưới dạng cửa sổ bật lên để báo hiệu cho người dùng khi một hành động được hoàn thành thành công hay không.


Ví dụ: tôi sẽ tạo một thông báo bật lên cho người dùng biết nếu cập nhật bài viết không thành công.

Xác thực giao diện người dùng

Xem quá trình xác thực back-end được hoàn thành như thế nào, chúng tôi phải mang đến cho người dùng trải nghiệm tốt hơn nữa bằng cách triển khai xác thực trên front end để người dùng phản hồi nhanh hơn.


Rất may, Aurelia có một trình cắm thêm xác thực và được triển khai phù hợp với giao diện linh hoạt. Điều này làm cho nó khá dễ dàng để tạo các quy tắc nghiệp vụ sẽ giới hạn số ký tự mà người dùng có thể nhập vào trường <input> cho tên bài viết.


Tôi sẽ sử dụng hệ thống ràng buộc thuộc tính Aurelia để thu thập các thông báo xác thực và sau đó hiển thị chúng trên giao diện người dùng. Tôi sẽ cần kết hợp thêm điều này với hệ thống bản địa hóa và đảm bảo rằng các thông báo được hiển thị bằng ngôn ngữ chính xác.

Hoàn thiện công việc

Phần còn lại của năm bao gồm làm việc trên các chi tiết nhỏ hơn. Nó yêu cầu tôi tạo những thứ như tải trình giữ chỗ. Tôi đặc biệt quyết định rằng tôi không muốn hiển thị trình giữ chỗ đang tải dưới dạng các phần tử màn hình riêng biệt.


Thay vào đó, tôi muốn cho người dùng biết rằng một phần tử đang được tải. Đó là lý do tại sao tôi sử dụng đường viền của phần tử đang được tải và thay vào đó, tạo cho chúng một hoạt ảnh tải trong suốt. Điều này được lấy cảm hứng từ ứng dụng di động Netflix hoạt động theo cách tương tự.


Vào thời điểm này, cuối năm đã đến và tôi đang làm việc trên trang chủ chính. Trang này sẽ chỉ hiển thị tất cả các cộng đồng mà chúng tôi hiện có. May mắn thay, hệ thống dựa trên thành phần mà tôi đã tạo trước đó khiến việc sử dụng lại hầu hết các đoạn mã mà tôi đã viết khá dễ dàng, vì vậy nhiệm vụ được hoàn thành nhanh chóng.


Năm cuối cùng cũng kết thúc và tôi hài lòng với công việc đã hoàn thành. Mặc dù dự án vẫn chưa được thực hiện, nhưng tôi biết rằng thành công đã nằm trong tầm tay của tôi.

2022 - Dặm cuối cùng

Năm nay là năm cuối cùng. Tôi không biết liệu mình có thực sự thực hiện mọi thứ mình muốn hay không, nhưng tôi biết mình phải làm bất kể điều gì đã xảy ra.


Tôi không muốn lặp lại công việc trong mùa hè như năm ngoái vì có khả năng nó sẽ còn nóng hơn năm ngoái.


Dự đoán của tôi đã trở thành sự thật và hóa ra Tokyo có nhiệt độ mùa hè nóng nhất vào năm 2022, được đo trong vòng 147 năm qua!

Thiết kế trang đích

Tôi bắt đầu bằng cách thiết kế trang đích. Câu hỏi là như sau.


Tôi muốn người dùng của mình cảm thấy thế nào khi họ truy cập trang đích của tôi?


Tôi không muốn người dùng cảm thấy đây là một trang web quá nghiêm túc, mà là một cộng đồng thân thiện và hợp tác.


Tôi nhận thấy rằng gần đây, các trang đích có hình ảnh minh họa trái ngược với hình ảnh của người thật, vì vậy sẽ rất hợp lý nếu bạn đi theo con đường này. Đó là lý do tại sao tôi quyết định chọn một bộ hình minh họa mà tôi đã mua trên Adobe Stock .


Trang đích phải đơn giản và cũng phải nhanh chóng mô tả mọi thứ mà trang web đang cung cấp. Điều này cũng phải được bản địa hóa, vì vậy tôi đã sử dụng tính năng bản địa hóa để dịch tất cả các tiêu đề trang đích và phụ đề được hiển thị.


Vấn đề kỹ thuật duy nhất phải được khắc phục là làm thế nào để giới thiệu màu sắc bên trong văn bản. May mắn thay, tôi đã có thể sử dụng tính năng tạo kiểu bên trong các định nghĩa dịch và sau đó, sử dụng Markdown để tạo động HTML sẽ được hiển thị trên trang đích.


Dữ liệu bắt buộc, chẳng hạn như “Chính sách quyền riêng tư” và “Điều khoản sử dụng” đã được mua trực tuyến và được dịch sang nhiều ngôn ngữ bằng Google Dịch.

Sẵn sàng cho những chuyện bất ngờ

Bây giờ đã đến lúc buộc tất cả các đầu lỏng lẻo, vì vậy tôi đã dành thời gian còn lại để đảm bảo rằng việc ghi nhật ký có mặt trong tất cả các chức năng của Lamda ở mặt sau. Điều này sẽ giúp tôi đảm bảo rằng nếu sự cố xảy ra, tôi sẽ biết chuyện gì đang xảy ra.


Vào thời điểm tôi đang hoàn thành, Chiến tranh ở Ukraine đã bắt đầu. Điều này một lần nữa làm gia tăng sự bất ổn của nền kinh tế toàn cầu nhưng tôi vẫn tiếp tục làm việc và giữ mình tập trung vào mục tiêu cuối cùng.

Do không giữ cho việc triển khai PWA được cập nhật, tôi phải đảm bảo rằng tất cả các tính năng đang hoạt động và do đó, cần phải phát triển thêm để cải thiện JavaScript và bộ nhớ đệm hình ảnh.


Tính năng ngoại tuyến cuối cùng đã được bật và ứng dụng hiện hoạt động bình thường như một ứng dụng ngoại tuyến.


Tôi cũng phải di chuyển những thay đổi mà tôi đã thực hiện ở mặt sau và thực sự phổ biến những thay đổi tôi đã thực hiện trên AppSync sang các khu vực khác. Vì sẽ quá cồng kềnh nếu làm điều đó trong quá trình phát triển, tôi không thực hiện thay đổi nào đối với các khu vực khác kể từ khi tôi bắt đầu phát triển.


Đối với môi trường cũng vậy. Sẽ lãng phí quá nhiều thời gian để liên tục xây dựng cả ba môi trường, vì vậy cuối cùng tôi đã dành chút thời gian để đồng bộ hóa tất cả các môi trường và chuyển mã sang UAT và Production.


Cuối cùng, tôi phải triển khai miền https://immersive.community, miền này sẽ phải hoạt động mà không có miền phụ „www“ và chuyển hướng đến trang chủ một cách chính xác.


Tại thời điểm này, chúng tôi đang ở vào sáng sớm ngày 25 tháng 4 năm 2022 . Dự án kéo dài 4 năm của tôi cuối cùng đã kết thúc. Tôi đã tạo bài viết đầu tiên trên trang web và đi ngủ. Tôi biết cuối cùng tôi đã thành công. Tôi không chỉ hoàn thành những gì đã đặt ra mà còn làm trước khi mùa hè đến.

Từ cuối cùng

Trớ trêu thay, những lời cuối cùng trong cuộc phiêu lưu của tôi, là đây không phải là kết thúc, mà chỉ là bắt đầu. Giờ đây, hệ thống đã hoạt động, nội dung cần được tạo cũng như quảng bá và quảng cáo cần thiết cho nhận thức về thương hiệu sẽ là một cuộc phiêu lưu hoàn toàn mới.


Nhưng, tôi thực sự đã học được gì từ bài tập này?


Chà, khá nhiều. Trước hết, tôi có thể tự tin nói rằng tôi sẽ không bao giờ tái phạm nữa.


Không phải tôi không hài lòng với kết quả, ngược lại, tôi rất hài lòng, nhưng đây là loại việc bạn làm một lần trong đời và sẽ không có ý nghĩa gì nếu bạn cố gắng vượt lên chính mình, chỉ đơn giản là để chứng minh mà bạn có thể làm điều đó tốt hơn nữa.


Tôi muốn biết liệu có thể xây dựng một hệ thống cấp doanh nghiệp với tư cách là một nhà phát triển solo hay không và tôi đã chứng minh rằng nó có thể được thực hiện với hệ thống công nghệ mà chúng tôi có sẵn.


Hơn bất cứ điều gì, đây là một tuyên bố cho mọi nhà phát triển đang làm việc trong dự án phụ của họ hoặc đang nghĩ đến việc bắt đầu một dự án.


Tôi có giới thiệu cách tiếp cận này cho các nhà phát triển khác không? Chắc chắn rồi. Không phải vì đó là cách làm tối ưu, mà chắc chắn là không.


Không yêu cầu sự giúp đỡ khi bạn gặp khó khăn chắc chắn không phải là cách nhanh nhất để giải quyết vấn đề, nhưng những gì nó sẽ làm là giúp bạn khám phá giới hạn của bản thân.


Khi bạn đã quyết định làm điều gì đó như thế này và bạn thành công, bạn sẽ biết rằng mọi thứ khác mà bạn quyết định làm sau đó sẽ dễ dàng đạt được hơn.


Tôi tin rằng câu chuyện của tôi sẽ thúc đẩy bạn hoàn thành bất cứ điều gì bạn đã bắt đầu bất kể bạn cảm thấy thế nào và ngay cả khi bạn không nhìn thấy cuối con đường mà bạn đang bước xuống, chỉ cần nhớ rằng “quay lại đó” không phải là nơi bạn muốn .


Nếu bạn thấy câu chuyện này đầy cảm hứng, hãy đăng ký kênh YouTube của tôi vì tôi sẽ bắt đầu tham gia khóa học lập trình “Full Stack Dev” nâng cao, nơi tôi sẽ đi sâu vào chi tiết về tất cả công nghệ mà tôi đã sử dụng để xây dựng Cộng đồng nhập vai.


Những gì tôi không đề cập đến trong bài viết này là nền tảng triết học và lý do cho cách tôi tiếp cận từng vấn đề và các kỹ thuật tôi đã sử dụng để phân tích và thiết kế giải pháp cho từng vấn đề.


Đây là một thành phần thậm chí còn quan trọng hơn việc chỉ đơn giản là biết các công nghệ và cách sử dụng chúng. Cách bạn tiếp cận một vấn đề và quá trình suy nghĩ của bạn, đưa bạn đến giải pháp, là điều mà tôi sẽ đi sâu trong các video YouTube của mình.


Đây sẽ là một cách tuyệt vời để các nhà phát triển học lập trình từ một người đã tạo ra một hệ thống trong thế giới thực và sẵn sàng chia sẻ kiến thức của mình. Hẹn gặp bạn trên YouTube!


Cũng được xuất bản tại đây