این سؤال تنها با زبان‌های PHP ، Python ، Go و JS (Node.js) قابل حل است.


دیجی‌کال‍ا قصد دارد برای بخش تحویل محصولات خود یک سامانه‌ی ساده‌ی ثبت پیشنهادات و انتقادات راه‌اندازی کند. از شما می‌خواهیم یک API برای این سامانه طراحی کنید.

جزئیات پروژه

پروژه‌ی اولیه را از این لینک دانلود کنید.

در این سؤال، یک REST API شامل endpoint های زیر باید پیاده‌سازی شود:

آدرس عنوان
GET / بررسی up بودن سرویس
POST /signup ثبت‌نام
POST /login ورود به حساب کاربری
POST /urls کوتاه کردن لینک
GET /urls دریافت لیست لینک‌های کوتاه‌شده
GET /{slug} لینک کوتاه‌شده

در این API هر کاربر باید یک توکن داشته باشد. این توکن برای هر کاربر ثابت است.

%align_right_start%

endpoint های موردنیاز

%align_end%

در همه‌ی endpoint ها، پاسخ باید به‌صورت JSON باشد.

اطلاعات ورودی به‌صورت application/x-www-form-urlencoded به endpoint ها ارسال می‌شوند.

بررسی up بودن سرویس

پاسخ این endpoint باید به‌صورت زیر باشد:

  • کد وضعیت: 200
  • بدنه: {"ok":true}

ثبت‌نام

دو پارامتر username و password باید به این endpoint ارسال شوند. در صورتی که حداقل یکی از این پارامترها ارسال نشده باشد یا برابر با رشته‌ی خالی باشد، پاسخ باید به‌صورت زیر باشد:

  • کد وضعیت: 400
  • بدنه: {"ok":false,"error":"no username or password provided"}

اگر کاربری با نام کاربری واردشده از قبل موجود باشد، پاسخ باید به‌صورت زیر باشد:

  • کد وضعیت: 400
  • بدنه: {"ok":false,"error":"user already exists"}

در غیر این‌صورت، کاربر باید ساخته شود، یک توکن یکتا برایش تولید شود و پاسخ به‌صورت زیر باشد:

  • کد وضعیت: 201
  • بدنه: {"ok":true,"token":"USER_TOKEN"}

ورود به حساب کاربری

دو پارامتر username و password باید به این endpoint ارسال شوند. در صورتی که حداقل یکی از این پارامترها ارسال نشده باشد یا برابر با رشته‌ی خالی باشد، پاسخ باید به‌صورت زیر باشد:

  • کد وضعیت: 400
  • بدنه: {"ok":false,"error":"no username or password provided"}

اگر نام کاربری یا رمز عبور نادرست باشد، پاسخ باید به‌صورت زیر باشد:

  • کد وضعیت: 400
  • بدنه: {"ok":false,"error":"invalid username or password"}

در غیر این‌صورت، پاسخ باید به‌صورت زیر باشد:

  • کد وضعیت: 200
  • بدنه: {"ok":true,"token":"USER_TOKEN"}

کوتاه کردن لینک

این endpoint نیازمند authentication است. در ریکوئست ارسالی مقدار هدر Authorization باید برابر با توکن کاربر باشد (بدون Bearer یا موارد مشابه).

پارامتر url (لینک) باید به این endpoint ارسال شود. در صورتی که این پارامتر ارسال نشده باشد یا برابر با رشته‌ی خالی باشد، پاسخ باید به‌صورت زیر باشد:

  • کد وضعیت: 400
  • بدنه: {"ok":false,"error":"no url provided"}

در غیر این‌صورت، لینک باید کوتاه شود و پاسخ به‌صورت زیر باشد (مقدار {slug} می‌تواند رندوم باشد):

  • کد وضعیت: 201
  • بدنه: {"ok":true,"url":"http://localhost/{slug}"}

دریافت لیست لینک‌های کوتاه‌شده

این endpoint نیازمند authentication است. در ریکوئست ارسالی مقدار هدر Authorization باید برابر با توکن کاربر باشد (بدون Bearer یا موارد مشابه).

این endpoint باید لیست لینک‌های کوتاه‌شده‌ی کاربر به همراه تعداد بازدید هر کدام را در قالب یک لیست برگرداند.

  • کد وضعیت: 200
  • مثالی از پاسخ:
[
    {
        "short_url": "http://localhost/SDas2",
        "url": "https://quera.org",
        "visits_count": 3
    },
    {
        "short_url": "http://localhost/zxcA54",
        "url": "https://google.com",
        "visits_count": 0
    }
]
JSON

لینک کوتاه‌شده

آدرس این درخواست به‌صورت /{slug} است که {slug} همان رشته‌ای است که به لینک کوتاه‌شده توسط برنامه تخصیص می‌یابد. اگر {slug} ورودی یافت نشود، پاسخ باید به‌صورت زیر باشد:

  • کد وضعیت: 404

در غیر این‌صورت، کاربر باید به لینک اصلی با کد پاسخ 301 هدایت شود.

نکات تکمیلی

نصب نیازمندی‌ها و اجرا

برای حل این سؤال می‌توانید از هر زبان و هر تکنولوژی‌ای که می‌خواهید استفاده کنید. به‌صورتی که در یک پوشه به نام api کد برنامه را نوشته و در فایلی به نام runner.sh که توسط sh اجرا می‌شود، باید برنامه‌ی خود را اجرا کنید. توجه کنید که حتماً باید Dockerfile مربوط به پروژه‌ی خود را برای ما ارسال کنید.

در پروژه‌ی اولیه، ۴ داکرفایل برای php، python، golang و node قرار دادیم که می‌توانید از آن‌ها مستقیماً استفاده کنید. در صورتی که از یکی از این زبان‌ها برای حل سؤال استفاده می‌کنید، کافیست که Dockerfile مربوط به آن را در پوشه‌ی api کپی کنید و طبق توضیحات داده شده، سؤال را حل کنید. برای نصب نیازمندی‌های پایتون از requirements.txt، برای پی‌اچ‌پی از composer.json، برای گولنگ از go.mod و برای نودجی‌اس از package.json استفاده کنید.

در صورتی که زبان مورد استفاده‌ی شما، چیزی به جز این ۴ مورد است، باید خودتان داکرفایلی در پوشه‌ی api به‌شکلی بنویسید که بتواند نیازمندی‌های پروژه‌ی شما را نصب کرده و برنامه‌ی شما را مانند داکرفایل‌های موجود اجرا کند.

  • نیازی به persistent بودن داده‌ها نیست!
  • سیستم داوری docker-compose.yml زیر را خارج از فولدر api پاسخ شما قرار می‌دهد و با دستور docker-compose up --build آن را اجرا می‌کند.
version: "3"

services:
  api:
    build: "./api"
    container_name: "api"
    ports:
      - "80:80"
YAML
docker-compose.yml
  • شما مجاز به تغییر یا ارسال docker-compose.yml دلخواه نیستید.
  • سرویس شما باید روی پورت 80 آدرس localhost قابل دسترسی باشد.
  • توصیه می‌کنیم در runner.sh خود APIتان را روی 0.0.0.0:80 اجرا کنید.

تغییر Dockerfile

امکان تغییر فایل Dockerfile وجود ندارد، اما در اسکریپت runner.sh می‌توانید هر دستوری را اجرا کنید.

نحوه ارسال پاسخ

شما می‌توانید تمامی محتوای موجود در پوشه‌ی api را تغییر دهید و هر فایلی که می‌خواهید اضافه یا کم کنید.

api
├──  api.py   # or main.go somefile.js anyfile.php name.any ...
├── Dockerfile
├── requirements.txt  # or go.mod package.json composer.json
└── runner.sh
Plain text

توجه کنید که نام فایل کد شما برای سیستم داوری اهمیتی ندارد و این خود شما هستید که در runner.sh از نام آن برای اجرای پروژه استفاده می‌کنید.

در نهایت این پوشه را zip کرده و ارسال کنید. توجه کنید که پس از extract کردن فایل zip شما، باید پوشه‌ی api را ببینیم که درون آن Dockerfile وجود دارد.


ارسال پاسخ برای این سؤال
فایلی انتخاب نشده است.