چجوری توی تیلویند کامپوننت ایجاد کنیم؟
بعضی موقع شده چند دکمه یا چند بخش استایل هایی کاملا شبیه به هم دارند این درست نیست به هر کدوم این استایل ها رو دوباره بدیم چون بهینه نیست و استایل ها یکیه و سند مارو شلوغ میکنه برای اینکه از شلوغ شدن صفحه جلوگیری بشه و کد ما تمیز تر و بهینه تر باشه از کامپوننت استفاده میکنیم
برای ایجاد کامپوننت توی تیلویند سی اس اس به سند input.css باید بریم و اونجا کامپوننت های خودمون رو بزاریم
حالا چجوری ؟
ما باید با کد زیر مشخص کنیم که میخوایم کامپوننت ایجاد کنیم:
با کد بالا شما میتونید بیس ایجاد کامپوننت خودتون رو ایجاد کنید داخل کریلی بریسس شما باید یک کلاس نام گذاری کنید طبق سکشنی که دارید میزنید یه کلاس مربوط بدید و داخل اون کلاس شما هم میتونید بصورت سی اس اس خام استایل هاتون رو تعریف کنید هم بصورت تیلویند بصورت سی اس اس خام در پایین مثال میزنم براتون:
با سی اس اس خام مثل مثال بالا میتونید استایلتون رو بدید و کلاس btn رو به سکشن یا دکمتون بدید
اگر میخواید استایل هاتون رو توی کامپوننت هم بصورت تیلویند باشه باید با
این کار رو انجام بدید مثالش رو پایین براتون میزنم:
میتونید مثل کد بالا استایلتون رو بصورت تیلویند تعریف کنید.
اگ کاربردی بود براتون لایک کنید حتمی
باتشکر.
< @undefinedee />
بعضی موقع شده چند دکمه یا چند بخش استایل هایی کاملا شبیه به هم دارند این درست نیست به هر کدوم این استایل ها رو دوباره بدیم چون بهینه نیست و استایل ها یکیه و سند مارو شلوغ میکنه برای اینکه از شلوغ شدن صفحه جلوگیری بشه و کد ما تمیز تر و بهینه تر باشه از کامپوننت استفاده میکنیم
برای ایجاد کامپوننت توی تیلویند سی اس اس به سند input.css باید بریم و اونجا کامپوننت های خودمون رو بزاریم
حالا چجوری ؟
ما باید با کد زیر مشخص کنیم که میخوایم کامپوننت ایجاد کنیم:
@layer components {}با کد بالا شما میتونید بیس ایجاد کامپوننت خودتون رو ایجاد کنید داخل کریلی بریسس شما باید یک کلاس نام گذاری کنید طبق سکشنی که دارید میزنید یه کلاس مربوط بدید و داخل اون کلاس شما هم میتونید بصورت سی اس اس خام استایل هاتون رو تعریف کنید هم بصورت تیلویند بصورت سی اس اس خام در پایین مثال میزنم براتون:
@layer components {
.btn{
display:flex;
justify-content: center;
align-items: center;
}
}با سی اس اس خام مثل مثال بالا میتونید استایلتون رو بدید و کلاس btn رو به سکشن یا دکمتون بدید
اگر میخواید استایل هاتون رو توی کامپوننت هم بصورت تیلویند باشه باید با
@apply
این کار رو انجام بدید مثالش رو پایین براتون میزنم:
@layer components {
.btn{
@apply flex justify-center items-center;
}
}میتونید مثل کد بالا استایلتون رو بصورت تیلویند تعریف کنید.
اگ کاربردی بود براتون لایک کنید حتمی
باتشکر.
< @undefinedee />
❤5
گزارش جدید Anthropic درباره سوءاستفاده از Claude منتشر شده و بخش مربوط به ایرانش خیلی جالبه:
حالا فهمدید چرا آنتروپیک حساب کلاد ایرانیهارو درجا میبست؟
چند نهاد حکومتی ایران از Claude برای «جنگ شناختی» و تبلیغات استفاده کردن؛ از طراحی عملیات و ساخت پرسونای جعلی تا تولید محتوای چندزبانه.
حالا فهمدید چرا آنتروپیک حساب کلاد ایرانیهارو درجا میبست؟
🎨 ساخت شکلهای جذاب با CSS و Clip-Path!
تا حالا خواستی یک عکس یا المان رو به شکل مثلث، ستاره، چندضلعی یا حتی شکلهای خاص نمایش بدی؟ 🤩
اینجاست که
🔹 با
مثلاً:
📌 کد بالا یک عنصر مربعی رو به شکل مثلث درمیاره. 🔺
چند مقدار پرکاربرد:
🔸
🔸
🔸
🔸
💡 نکته:
تا حالا خواستی یک عکس یا المان رو به شکل مثلث، ستاره، چندضلعی یا حتی شکلهای خاص نمایش بدی؟ 🤩
اینجاست که
clip-path وارد میشه!🔹 با
clip-path میتونیم قسمت مشخصی از یک عنصر رو نمایش بدیم و بقیه قسمتها رو برش بزنیم.مثلاً:
.box {
width: 200px;
height: 200px;
background: dodgerblue;
clip-path: polygon(
50% 0%,
100% 100%,
0% 100%
);
}📌 کد بالا یک عنصر مربعی رو به شکل مثلث درمیاره. 🔺
چند مقدار پرکاربرد:
🔸
circle() → دایره🔸
ellipse() → بیضی🔸
polygon() → چندضلعی🔸
inset() → برش از داخل💡 نکته:
clip-path برای طراحی کارتها، تصاویر، بنرها و افکتهای مدرن سایت خیلی کاربردیه.برای نصب Font Awesome با استفاده از npm، میتوانید مراحل زیر را دنبال کنید:
▎1. نصب npm
مطمئن شوید که Node.js و npm بر روی سیستم شما نصب شدهاند. اگر Node.js را نصب کردهاید، npm بهطور خودکار نصب میشود.
▎2. ایجاد پروژه جدید (اختیاری)
اگر هنوز یک پروژه جدید ندارید، میتوانید با استفاده از دستورات زیر یک پروژه جدید ایجاد کنید:
▎3. نصب Font Awesome
برای نصب Font Awesome، دستور زیر را در ترمینال اجرا کنید:
▎4. استفاده از Font Awesome در پروژه
پس از نصب، شما باید فایلهای CSS و JS مربوط به Font Awesome را در پروژه خود وارد کنید. برای این کار، میتوانید به فایل CSS خود (مثلاً style.css) و یا به HTML خود (مثلاً index.html) لینک دهید.
▎روش اول: استفاده در HTML
در فایل HTML خود، قبل از تگ </head>، لینک CSS و JS را اضافه کنید:
▎روش دوم: استفاده در CSS
اگر میخواهید از Font Awesome در CSS استفاده کنید، میتوانید به صورت زیر عمل کنید:
▎5. استفاده از آیکونها
حالا شما میتوانید از آیکونهای Font Awesome در HTML خود استفاده کنید. به عنوان مثال:
با دنبال کردن این مراحل، شما میتوانید Font Awesome را به پروژه خود اضافه کرده و از آن استفاده کنید.
▎1. نصب npm
مطمئن شوید که Node.js و npm بر روی سیستم شما نصب شدهاند. اگر Node.js را نصب کردهاید، npm بهطور خودکار نصب میشود.
▎2. ایجاد پروژه جدید (اختیاری)
اگر هنوز یک پروژه جدید ندارید، میتوانید با استفاده از دستورات زیر یک پروژه جدید ایجاد کنید:
mkdir my-project
cd my-project
npm init -y
▎3. نصب Font Awesome
برای نصب Font Awesome، دستور زیر را در ترمینال اجرا کنید:
npm install --save @fortawesome/fontawesome-free
▎4. استفاده از Font Awesome در پروژه
پس از نصب، شما باید فایلهای CSS و JS مربوط به Font Awesome را در پروژه خود وارد کنید. برای این کار، میتوانید به فایل CSS خود (مثلاً style.css) و یا به HTML خود (مثلاً index.html) لینک دهید.
▎روش اول: استفاده در HTML
در فایل HTML خود، قبل از تگ </head>، لینک CSS و JS را اضافه کنید:
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<title>Font Awesome Example</title>
</head>
<body>
<h1>مثال آیکون Font Awesome</h1>
<i class="fas fa-camera"></i> <!-- آیکون دوربین -->
</body>
</html>
▎روش دوم: استفاده در CSS
اگر میخواهید از Font Awesome در CSS استفاده کنید، میتوانید به صورت زیر عمل کنید:
@import '~@fortawesome/fontawesome-free/css/all.min.css';
▎5. استفاده از آیکونها
حالا شما میتوانید از آیکونهای Font Awesome در HTML خود استفاده کنید. به عنوان مثال:
<i class="fas fa-user"></i> <!-- آیکون کاربر -->
<i class="fab fa-github"></i> <!-- آیکون گیتهاب -->
با دنبال کردن این مراحل، شما میتوانید Font Awesome را به پروژه خود اضافه کرده و از آن استفاده کنید.
❤3
🔶 سایت Upload.am یک سرویس آپلود و دانلود ارمنستانی است که ۲۵ گیگابایت فضای رایگان در اختیار کاربران قرار میدهد.
همچنین، امکان خرید پلن های آن با ارز های دیجیتال فراهم است؛ بنابراین کاربران ایرانی میتوانند بدون دردسر و با استفاده از ارز دیجیتال، پلن خود را ارتقا دهند.
البته نسخه Free فقط فایل ها در ۳۰ روز نگه می دارد و بعد از آن حذف می شوند و اگر می خوای فایل ها حذف نشوند باید نسخه Keep رو خریداری کنید.
https://upload.am
#معرفی
همچنین، امکان خرید پلن های آن با ارز های دیجیتال فراهم است؛ بنابراین کاربران ایرانی میتوانند بدون دردسر و با استفاده از ارز دیجیتال، پلن خود را ارتقا دهند.
البته نسخه Free فقط فایل ها در ۳۰ روز نگه می دارد و بعد از آن حذف می شوند و اگر می خوای فایل ها حذف نشوند باید نسخه Keep رو خریداری کنید.
https://upload.am
#معرفی
upload.am
Free 25 GB Storage with Upload.am: Secure, No Data Retention
Unlimited download speed on every plan — including free. Fast, affordable, legal file hosting.
❤4
سلام، خسته نباشید 🌱
یه نکتهی کوچیک راجع به Tailwind CSS میخواستم بگم که شاید به کارتون بیاد.
توی طراحی معمولاً برای هر سکشن یا بخشی که میخوایم پیادهسازی کنیم، یه Width، Height و... مشخص شده که معمولاً بر اساس Pixel هست.
حالا برای تبدیل این مقدارها به مقادیر Tailwind، معمولاً میتونیم از مقادیر موجود توی داکیومنت خود Tailwind استفاده کنیم؛ ولی خب بعضی وقتا ممکنه داکیومنت برامون باز نشه، بهش دسترسی نداشته باشیم یا اصلاً حوصلهی باز کردنش رو نداشته باشیم 😄
اینجا یه راه خیلی ساده داریم 👇
مثلاً فرض کنید عرض سکشن ما 250px هست و میخوایم مقدار مناسبش رو برای Tailwind پیدا کنیم.
کافیه 250 رو تقسیم بر 4 کنیم:
250 ÷ 4 = 62.5
پس مقدار Tailwind ما میشه:
w-62.5
البته بسته به نیازتون میتونید مقدار رو گرد کنید و از "w-62" یا مقدار دقیقتر استفاده کنید.
🔸 دلیلش هم اینه که مقیاس پیشفرض Tailwind معمولاً بر اساس هر واحد = 0.25rem هست که در تنظیمات پیشفرض، معادل 4px در نظر گرفته میشه.
پس بهصورت خلاصه:
Pixel ÷ 4 = مقدار Tailwind
مثلاً:
100px → 25
200px → 50
250px → 62.5
400px → 100
یه ترفند سادهست، ولی وقتی زیاد با Tailwind کار کنید، خیلی به دردتون میخوره. 🚀
یه نکتهی کوچیک راجع به Tailwind CSS میخواستم بگم که شاید به کارتون بیاد.
توی طراحی معمولاً برای هر سکشن یا بخشی که میخوایم پیادهسازی کنیم، یه Width، Height و... مشخص شده که معمولاً بر اساس Pixel هست.
حالا برای تبدیل این مقدارها به مقادیر Tailwind، معمولاً میتونیم از مقادیر موجود توی داکیومنت خود Tailwind استفاده کنیم؛ ولی خب بعضی وقتا ممکنه داکیومنت برامون باز نشه، بهش دسترسی نداشته باشیم یا اصلاً حوصلهی باز کردنش رو نداشته باشیم 😄
اینجا یه راه خیلی ساده داریم 👇
مثلاً فرض کنید عرض سکشن ما 250px هست و میخوایم مقدار مناسبش رو برای Tailwind پیدا کنیم.
کافیه 250 رو تقسیم بر 4 کنیم:
250 ÷ 4 = 62.5
پس مقدار Tailwind ما میشه:
w-62.5
البته بسته به نیازتون میتونید مقدار رو گرد کنید و از "w-62" یا مقدار دقیقتر استفاده کنید.
🔸 دلیلش هم اینه که مقیاس پیشفرض Tailwind معمولاً بر اساس هر واحد = 0.25rem هست که در تنظیمات پیشفرض، معادل 4px در نظر گرفته میشه.
پس بهصورت خلاصه:
Pixel ÷ 4 = مقدار Tailwind
مثلاً:
100px → 25
200px → 50
250px → 62.5
400px → 100
یه ترفند سادهست، ولی وقتی زیاد با Tailwind کار کنید، خیلی به دردتون میخوره. 🚀
❤3
📌 حلقهها در جاوااسکریپت؛ کدت رو چندباره کن بدون خستگی!
حلقهها بهت اجازه میدن یه کار رو تکراری اجرا کنی. تو جاوااسکریپت چند نوع حلقه داریم که هرکدوم جایگاه خودشون رو دارن:
🔁 for کلاسیک
وقتی تعداد دفعات مشخصه:
🔁 while
وقتی شرط نامشخصه و ممکنه اصلاً اجرا نشه:
🔁 do...while
حداقل یک بار اجرا میشه، حتی اگر شرط غلط باشه:
🔁 for...of (مدرن)
برای آرایهها و اشیاء قابل تکرار (iterable):
🔁 for...in
برای کلیدهای object (با احتیاط استفاده کن):
⚠️ نکته مهم:
از for...in روی آرایه استفاده نکن (ترتیب رو رعایت نمیکنه و خواص اضافی رو هم میاره). به جاش از for...of یا forEach استفاده کن.
✅ عملکرد:
حلقههای for و while سرعت بالایی دارن، ولی برای خوانایی کد، for...of و متدهای مدرن مثل map، filter رو ترجیح بده.
حلقهها بهت اجازه میدن یه کار رو تکراری اجرا کنی. تو جاوااسکریپت چند نوع حلقه داریم که هرکدوم جایگاه خودشون رو دارن:
🔁 for کلاسیک
وقتی تعداد دفعات مشخصه:
for (let i = 0; i < 5; i++) {
console.log(i); // 0 1 2 3 4
}🔁 while
وقتی شرط نامشخصه و ممکنه اصلاً اجرا نشه:
let n = 3;
while (n > 0) {
console.log(n--);
}
🔁 do...while
حداقل یک بار اجرا میشه، حتی اگر شرط غلط باشه:
let x = 10;
do {
console.log(x);
} while (x < 5); // چاپ ۱۰
🔁 for...of (مدرن)
برای آرایهها و اشیاء قابل تکرار (iterable):
const colors = ['red', 'green', 'blue'];
for (let c of colors) {
console.log(c);
}
🔁 for...in
برای کلیدهای object (با احتیاط استفاده کن):
const user = {name: 'Ali', age: 25};
for (let key in user) {
console.log(key, user[key]);
}⚠️ نکته مهم:
از for...in روی آرایه استفاده نکن (ترتیب رو رعایت نمیکنه و خواص اضافی رو هم میاره). به جاش از for...of یا forEach استفاده کن.
✅ عملکرد:
حلقههای for و while سرعت بالایی دارن، ولی برای خوانایی کد، for...of و متدهای مدرن مثل map، filter رو ترجیح بده.
❤2
⏺امروز، روز آتش نشانه.
به یاد جاویدنام حمید مهدوی آتش نشانی که خودشو فدا کرد تا معترضین رو نجات بده و در نهایت با شلیک گلوله، 18 دی ماه به قتل رسید.
به یاد جاویدنام حمید مهدوی آتش نشانی که خودشو فدا کرد تا معترضین رو نجات بده و در نهایت با شلیک گلوله، 18 دی ماه به قتل رسید.
❤6
🔴 امروز 10 مهر، جشن باستانی مهرگانه؛
معنی کلمه مهرگان یعنی پیروزی نور بر تاریکی.
مردم این روز رو در کنار هم جشن میگیرن چون تو همچین روزی فریدون ضحاک رو شکست داد و همه به روشنایی و عدالت رسیدن.
این روز بعد از عید نوروز بزرگترین جشن تو تاریخ ایرانه. وقتی همچین روزی فرا میرسید مردم به هم هدیه میدادن و سعی میکردن همو خوشحال کنن.
معنی کلمه مهرگان یعنی پیروزی نور بر تاریکی.
❤2
آچار فرانسه ریسپانسیو در CSS؛ آشنایی با ویژگی aspect-ratio
تا حالا براتون پیش اومده که بخواهید یک تصویر، ویدیو یا ظرف (Container) همیشه یک نسبت ابعاد مشخص (مثل مربع ۱:۱ یا مستطیل ۱۶:۹) رو حفظ کنه، حتی وقتی اندازه صفحه نمایش تغییر میکنه؟
قبل از این که ویژگی aspect-ratio به CSS اضافه بشه، طراحان وب مجبور بودند از ترفندهای عجیبی مثل تکنیک "Padding-bottom hack" (دادن پدینگ درصدی بر اساس عرض) استفاده کنند که کدها رو پیچیده و خواندنشون رو سخت میکرد. اما خوشبختانه امروزه با این ویژگی مدرن، کار بسیار راحتتر شده است.
چرا باید از aspect-ratio استفاده کنیم؟
جلوگیری از پرش محتوا (CLS): وقتی تصاویر یا ویدیوها لود میشن، فضای خالی خودشون رو از قبل رزوم میکنن و صفحه ناگهان به هم نمیریزه.
کدنویسی تمیز و کوتاه: نیازی به محاسبات پیچیده ریاضی یا کدهای اضافی نیست.* ریسپانسیو خودکار: به راحتی با تغییر سایز مرورگر، ابعاد عنصر متناسب با نسبت تعیینشده تغییر میکنه.
نحوه استفاده و مثالهای کاربردی
نحوهی نوشتن این ویژگی بسیار ساده است. شما فقط کافیه نسبت عرض به ارتفاع رو به شکل عرض / ارتفاع جلوی آن بنویسید:
نکته حرفهای:
شما حتی میتونید مقادیر رو به صورت اعشاری هم وارد کنید؛ مثلاً aspect-ratio: 1.5 دقیقا همان کارکرد aspect-ratio: 3 / 2 رو داره. همچنین ترکیب این ویژگی با object-fit: cover روی تصاویر باعث میشه عکسها بدون به هم خوردن دفرمه شدن، به زیبایی درون قاب خودشان جای بگیرند.
تا حالا براتون پیش اومده که بخواهید یک تصویر، ویدیو یا ظرف (Container) همیشه یک نسبت ابعاد مشخص (مثل مربع ۱:۱ یا مستطیل ۱۶:۹) رو حفظ کنه، حتی وقتی اندازه صفحه نمایش تغییر میکنه؟
قبل از این که ویژگی aspect-ratio به CSS اضافه بشه، طراحان وب مجبور بودند از ترفندهای عجیبی مثل تکنیک "Padding-bottom hack" (دادن پدینگ درصدی بر اساس عرض) استفاده کنند که کدها رو پیچیده و خواندنشون رو سخت میکرد. اما خوشبختانه امروزه با این ویژگی مدرن، کار بسیار راحتتر شده است.
چرا باید از aspect-ratio استفاده کنیم؟
جلوگیری از پرش محتوا (CLS): وقتی تصاویر یا ویدیوها لود میشن، فضای خالی خودشون رو از قبل رزوم میکنن و صفحه ناگهان به هم نمیریزه.
کدنویسی تمیز و کوتاه: نیازی به محاسبات پیچیده ریاضی یا کدهای اضافی نیست.* ریسپانسیو خودکار: به راحتی با تغییر سایز مرورگر، ابعاد عنصر متناسب با نسبت تعیینشده تغییر میکنه.
نحوه استفاده و مثالهای کاربردی
نحوهی نوشتن این ویژگی بسیار ساده است. شما فقط کافیه نسبت عرض به ارتفاع رو به شکل عرض / ارتفاع جلوی آن بنویسید:
.square-box {
width: 100%;
aspect-ratio: 1 / 1;
}
.video-container {
width: 100%;
aspect-ratio: 16 / 9;
}
.hero-banner {
width: 100%;
aspect-ratio: 21 / 9;
}نکته حرفهای:
شما حتی میتونید مقادیر رو به صورت اعشاری هم وارد کنید؛ مثلاً aspect-ratio: 1.5 دقیقا همان کارکرد aspect-ratio: 3 / 2 رو داره. همچنین ترکیب این ویژگی با object-fit: cover روی تصاویر باعث میشه عکسها بدون به هم خوردن دفرمه شدن، به زیبایی درون قاب خودشان جای بگیرند.
❤4
Forwarded from </awat> (awat)
Idempotent & Safe methods در HTTP 🌐
دو مفهوم مهم HTTP که خیلی وقتها با هم اشتباه گرفته میشن: Safe و Idempotent.
SAFE METHOD 🛡
یه متد وقتی Safe (ایمن) محسوب میشه که هدف اصلی ریکوئست فقط خوندن اطلاعات باشه و منجر به تغییر معنادار و عمدی resource نشه.
مثلا:
اینجا فقط اطلاعات کاربر رو میخونیم. پس GET یه متد safe محسوب میشه.
البته سرور ممکنه برای این ریکوئست لاگ یا کش ایجاد کنه. اینها safe بودن GET رو نقض نمیکنن. چون منظور از تغییر، تغییر هدفمند و عمدی هست. مثل عوض کردن نام کاربر.
HEAD و OPTIONS هم safe هستن.
اما POST و PUT و PATCH و DELETE برای ایجاد تغییر طراحی شدن.
IDEMPOTENT METHOD 🔄
idempotent (هم توان؟!) بودن یعنی اگر یه ریکوئست رو چند بار اجرا کنیم اثر نهایی اون روی سرور با اجرای یکباره ریکوئست یکسان باشه.
به زبون ریاضی:
f(f(x)) = f(x)
مثلا اگر این ریکوئست رو هزار بار هم بفرستیم، در نهایت داریم: name = awat
پس PUT با اینکه safe نیست، idempotent هست.
DELETE هم idempotent محسوب میشه:
بار اول کاربر حذف میشه. ریکوئستهای بعدی ممکنه 404 برگردونن، اما وضعیت نهایی همچنان اینه که کاربر حذف شده. دقیقا مثل دفعه اول.
مشخصه که همه متدهای safe تو دسته idempotentها هم قرار میگیرن.
و یه نکته مهم 🧨
idempotency فقط به اسم متد وابسته نیست. نحوه پیادهسازی اندپوینت هم اهمیت داره.
مثلا
هر بار که ریکوئست رو میفرستیم یه واحد به سن اضافه میشه.
اینجا اجرای دوباره ریکوئست، اثر جدیدی ایجاد میکنه؛ بنابراین این عملیات idempotent نیست.
البته گفتیم HTTP متد PUT رو idempotent معرفی کرده. پس این اندپوینت درست طراحی نشده و برای این عملیات بهتره از PATCH استفاده کنیم.
حالا خود PATCH تو کدوم دستهست؟
ضمانت خاصی براش نداریم. این موضوع به نحوه طراحیمون بستگی داره.
مثلا این یه عملیات idempotent هست:
اما اگر همچین اندپوینتی داشته باشیم:
نتیجه میشه:
18 >> 19 >> 20
پس non-idempotent محسوب میشه.
POST و خطر Retry ☠️
POST رسما idempotent تعریف نشده. این موضوع تو عملیاتهای حساسی مثل تراکنش اهمیت زیادی داره.
مثلا:
فرض کنید پرداخت با موفقیت انجام میشه، اما به هر دلیلی کلاینت برای همین پرداخت دوباره درخواست بفرسته.
اگر سرور این دو ریکوئست رو دو تراکنش متمایز در نظر بگیره، مبلغ دو بار از موجودی کاربر کسر میشه.
برای جلوگیری از این مشکل میتونیم از idempotency key داخل هدر استفاده کنیم:
سرور این کلید و نتیجه تراکنش رو ذخیره میکنه. اگر همون ریکوئست دوباره با کلید "abc123" فرستاده شه (retry)، سرور به جای انجام دوباره تراکنش، نتیجه قبلی رو برمیگردونه.
البته این کلید باعث نمیشه POST ماهیت idempotent بگیره؛ ما با این مکانیزم صرفا یه عملیات مشخص رو در برابر ریکوئستهای تکراری مقاوم میکنیم.
پس دو سوال متفاوت داریم:
Safe:
Idempotent:
مطالعه بیشتر در MDN 🤓
Safe
Idempotent
Idempotency-Key header
@awat_dev
دو مفهوم مهم HTTP که خیلی وقتها با هم اشتباه گرفته میشن: Safe و Idempotent.
SAFE METHOD 🛡
یه متد وقتی Safe (ایمن) محسوب میشه که هدف اصلی ریکوئست فقط خوندن اطلاعات باشه و منجر به تغییر معنادار و عمدی resource نشه.
مثلا:
GET /users/1
اینجا فقط اطلاعات کاربر رو میخونیم. پس GET یه متد safe محسوب میشه.
البته سرور ممکنه برای این ریکوئست لاگ یا کش ایجاد کنه. اینها safe بودن GET رو نقض نمیکنن. چون منظور از تغییر، تغییر هدفمند و عمدی هست. مثل عوض کردن نام کاربر.
HEAD و OPTIONS هم safe هستن.
اما POST و PUT و PATCH و DELETE برای ایجاد تغییر طراحی شدن.
IDEMPOTENT METHOD 🔄
idempotent (هم توان؟!) بودن یعنی اگر یه ریکوئست رو چند بار اجرا کنیم اثر نهایی اون روی سرور با اجرای یکباره ریکوئست یکسان باشه.
به زبون ریاضی:
f(f(x)) = f(x)
مثلا اگر این ریکوئست رو هزار بار هم بفرستیم، در نهایت داریم: name = awat
PUT /users/1
{
"name": "awat"
}
پس PUT با اینکه safe نیست، idempotent هست.
DELETE هم idempotent محسوب میشه:
DELETE /users/1
بار اول کاربر حذف میشه. ریکوئستهای بعدی ممکنه 404 برگردونن، اما وضعیت نهایی همچنان اینه که کاربر حذف شده. دقیقا مثل دفعه اول.
مشخصه که همه متدهای safe تو دسته idempotentها هم قرار میگیرن.
و یه نکته مهم 🧨
idempotency فقط به اسم متد وابسته نیست. نحوه پیادهسازی اندپوینت هم اهمیت داره.
مثلا
PUT /users/1
{
"operation": "increment_age"
}
هر بار که ریکوئست رو میفرستیم یه واحد به سن اضافه میشه.
اینجا اجرای دوباره ریکوئست، اثر جدیدی ایجاد میکنه؛ بنابراین این عملیات idempotent نیست.
البته گفتیم HTTP متد PUT رو idempotent معرفی کرده. پس این اندپوینت درست طراحی نشده و برای این عملیات بهتره از PATCH استفاده کنیم.
حالا خود PATCH تو کدوم دستهست؟
ضمانت خاصی براش نداریم. این موضوع به نحوه طراحیمون بستگی داره.
مثلا این یه عملیات idempotent هست:
PATCH /users/1
{
"name": "awat"
}
اما اگر همچین اندپوینتی داشته باشیم:
PATCH /users/1
{
"operation": "increment_age"
}
نتیجه میشه:
18 >> 19 >> 20
پس non-idempotent محسوب میشه.
POST و خطر Retry ☠️
POST رسما idempotent تعریف نشده. این موضوع تو عملیاتهای حساسی مثل تراکنش اهمیت زیادی داره.
مثلا:
POST /payments
{
"amount": 100
}
فرض کنید پرداخت با موفقیت انجام میشه، اما به هر دلیلی کلاینت برای همین پرداخت دوباره درخواست بفرسته.
اگر سرور این دو ریکوئست رو دو تراکنش متمایز در نظر بگیره، مبلغ دو بار از موجودی کاربر کسر میشه.
برای جلوگیری از این مشکل میتونیم از idempotency key داخل هدر استفاده کنیم:
POST /payments
Idempotency-Key: abc123
{
"amount": 100
}
سرور این کلید و نتیجه تراکنش رو ذخیره میکنه. اگر همون ریکوئست دوباره با کلید "abc123" فرستاده شه (retry)، سرور به جای انجام دوباره تراکنش، نتیجه قبلی رو برمیگردونه.
البته این کلید باعث نمیشه POST ماهیت idempotent بگیره؛ ما با این مکانیزم صرفا یه عملیات مشخص رو در برابر ریکوئستهای تکراری مقاوم میکنیم.
پس دو سوال متفاوت داریم:
Safe:
هدف از طراحی این عملیات تغییر عمدی در سرور بوده؟
Idempotent:
اگر همین ریکوئست رو دوباره بفرستیم، وضعیت نهایی سرور مثل نتیجه اجرای اول باقی میمونه؟
مطالعه بیشتر در MDN 🤓
Safe
Idempotent
Idempotency-Key header
@awat_dev
❤4
اگ طرحی ندارید یا فکر میکنید طرح از کجا بیارید هوش مصنوعی
https://stitch.withgoogle.com/
کمکتون میکنه فقط کافیه بگین چه وبسایتی میخواین بهتون دیزاین رو تحویل میده یعنی تو توضیح میدی چه سایتی میخوای؛ مثلاً فروشگاه لباس فارسی، و هوش مصنوعی بر اساس توضیحاتت طرح صفحات رو تولید میکنه
https://stitch.withgoogle.com/
کمکتون میکنه فقط کافیه بگین چه وبسایتی میخواین بهتون دیزاین رو تحویل میده یعنی تو توضیح میدی چه سایتی میخوای؛ مثلاً فروشگاه لباس فارسی، و هوش مصنوعی بر اساس توضیحاتت طرح صفحات رو تولید میکنه
1❤3