سریع چارچوبی است که برای توسعه وب back-end طراحی شده است. این گزینه جایگزین سبک تری را برای چارچوب های سنگین تر Node.js API مانند Hapi و Express ارائه می دهد. از جولای 2020 ، Fastify سومین نسخه از این چارچوب را منتشر کرد.

این نسخه سوم دارای قابلیت اعتبار سنجی بهبود یافته برای تأیید درخواست های ورودی و خروجی ، به عنوان پارامترهای درخواست است. علاوه بر این ، نسخه سوم این چارچوب ادعاهای توانمندی خود را در مورد سریعترین فریم ورک Node.js در مقایسه با Koa ، Resitfy ، Hapi و Express تلفیق می کند. اطلاعات بیشتر را می توان در صفحه معیارها.

Fastify به دلیل طراحی سبک بسیار محبوبیت زیادی کسب کرده است. با این حال ، توجه زیادی به آن می شود اکوسیستم پلاگین. Fastify این ایده را اتخاذ کرده است که همه چیز یک پلاگین است ، در حالی که با JavaScript همه چیز یک شی است. به شما این امکان را می دهد تا به سرعت قابلیت های پروژه خود را به عنوان یک افزونه محصور کرده و آن را توزیع کنید تا سایر پروژه ها بتوانند از کد شما استفاده کنند.

بیایید با این آموزش شروع کنیم. با جنبه های زیر Fastify آشنا خواهید شد:

  • چگونه اولین Fastify API خود را تنظیم کنیم
  • نحوه تعریف Fastify مسیرهای API
  • نحوه افزودن اعتبار طرح به درخواست ها
  • نحوه بارگیری و استفاده از افزونه های Fastify
  • چگونه می توان قلاب های Fastify را تعریف کرد

الزامات و نصب

برای دنبال کردن این آموزش ، به موارد زیر احتیاج دارید:

  1. آخرین نسخه Node.js
  2. ابزاری برای ارسال درخواست ، مانند حلقه یا پستچی

بعد ، مطمئن شوید که یک پروژه Node.js خالی ایجاد کرده اید. اگر هنوز یکی ندارید ، می توانید از دستور زیر برای راه اندازی پروژه خود استفاده کنید:

npm init -y

در آخر ، ما می خواهیم این وابستگی Fastify را به پروژه خود اضافه کنیم:

npm i fastify --save

همه خوبند؟ بیایید در مرحله بعدی تنظیمات اولیه API خود را ایجاد کنیم.

مرحله 1: تنظیم اولیه API

ابتدا ، بیایید تنظیمات اولیه API خود را ایجاد کنیم. برای شروع ، ما باید یک فایل جدید به نام ایجاد کنیم index.js در ریشه پروژه ما:

touch index.js

بعد ، بیایید تنظیمات اساسی سرور را اضافه کنیم. کد زیر را کپی کنید:


const app = require('fastify')({
    logger: true
})


app.get("https://www.sitepoint.com/", function (req, reply) {
    reply.send({ hello: 'world' })
})


app.listen(3000, (err, address) => {
    if (err) {
        app.log.error(err)
        process.exit(1)
    }
    app.log.info(`server listening on ${address}`)
})

در اینجا چند مورد اتفاق می افتد. ما ابتدا شیtif Fastify را بارگذاری کرده و ورود به سیستم را فعال می کنیم. بعد ، ما یک مسیر ریشه را اعلام می کنیم که با پاسخ JSON پاسخ می دهد. آخرین قسمت قطعه کد نشان می دهد که ما در حال گوش دادن به پورت 3000 برنامه برای دریافت درخواست هستیم.

اگر تنظیمات اصلی سرور شما کار می کند ، تأیید کنیم. ابتدا باید سرور را با اجرای سرور شروع کنیم index.js فایل:

node index.js

پس از آن ، به http://localhost:3000 در مرورگر خود باید پاسخ زیر را مشاهده کنید:

{
    "hello": "world"
}

موفق شدی؟ برای تعریف مسیرهای مختلف CRUD به مرحله 2 برویم.

مرحله 2: مسیرهای CRUD را تعریف کنید

API فقط با مسیرهای GET فایده ای ندارد. بیایید مسیرهای بیشتری را برای مدیریت وبلاگ ها تعریف کنیم. بنابراین ، بیایید مسیرهای زیر را ایجاد کنیم:

  • کلیه وبلاگها را در / api / blogs دریافت کنید
  • یک وبلاگ در / api / blogs / دریافت کنید: شناسه
  • پست اضافه کردن وبلاگ در / api / وبلاگ ها
  • وبلاگ را به روز کنید در / api / blogs /: شناسه
  • حذف وبلاگ در / api / blogs /: id

اولین کاری که باید انجام شود ایجاد یک کنترل کننده وبلاگ است.

مرحله 2.1: ایجاد کنترل کننده بلاگ ها

برای تمیز نگه داشتن کد خود ، بیایید a را تعریف کنیم controller پوشه در ریشه پروژه. در اینجا ، ما یک پرونده به نام ایجاد می کنیم blogs.js.

این فایل شامل برخی از داده های نسخه ی نمایشی برای جلوگیری از پیچیده شدن این آموزش با یکپارچه سازی پایگاه داده است. بنابراین ، ما از یک آرایه حاوی اشیا blog وبلاگ استفاده می کنیم که هر کدام حاوی شناسه و عنوان عنوان هستند.

علاوه بر این ، ما کنترل کننده های مختلف را برای تمام مسیرهای فوق در این فایل تعریف می کنیم. یک کنترل کننده همیشه الف را قبول می کند req (درخواست) و reply پارامتر. پارامتر درخواست برای دسترسی به پارامترهای درخواست یا درخواست داده های بدن مفید است.

کد زیر را به کد خود اضافه کنید /controller/blogs.js فایل:


let blogs = [
    {
        id: 1,
        title: 'This is an experiment'
    },
    {
        id: 2,
        title: 'Fastify is pretty cool'
    },
    {
        id: 3,
        title: 'Just another blog, yea!'
    }
]


const getAllBlogs = async (req, reply) => {
    return blogs
}

const getBlog = async (req, reply) => {
    const id = Number(req.params.id) 
    const blog = blogs.find(blog => blog.id === id)
    return blog
}

const addBlog = async (req, reply) => {
    const id = blogs.length + 1 
    const newBlog = {
        id,
        title: req.body.title
    }

    blogs.push(newBlog)
    return newBlog
}

const updateBlog = async (req, reply) => {
    const id = Number(req.params.id)
    blogs = blogs.map(blog => {
        if (blog.id === id) {
            return {
                id,
                title: req.body.title
            }
        }
    })

    return {
        id,
        title: req.body.title
    }
}

const deleteBlog = async (req, reply) => {
    const id = Number(req.params.id)

    blogs = blogs.filter(blog => blog.id !== id)
    return { msg: `Blog with ID ${id} is deleted` }
}

module.exports = {
    getAllBlogs,
    getBlog,
    addBlog,
    updateBlog,
    deleteBlog
}

توجه داشته باشید که چگونه می توانیم به پارامتر درخواست برای مسیرهایی مانند /api/blogs/:id از طريق req.params.id. برای مسیرهای POST و PUT ، از طریق می توانیم به قسمت اصلی درخواست دسترسی پیدا کنیم req.body.

در مرحله 2.2 ، راهبران مسیر را به اشیا route مسیر متصل خواهیم کرد.

مرحله 2.2: مسیرهای بلاگ و کنترل کننده وبلاگ های زوج را تعریف کنید

باز هم ، برای تمیز نگه داشتن کد خود ، بیایید a را تعریف کنیم routes پوشه در ریشه پروژه. در اینجا ، ما یک پرونده به نام ایجاد می کنیم blogs.js. این فایل شی routes مسیرها را برای مسیرهای وبلاگ ما نگهداری می کند:

mkdir routes
cd routes
touch blogs.js

خوشبختانه ، Fastify به ما اجازه می دهد تا یک آرایه حاوی اشیا route مسیر را تعریف کنیم. در اینجا می توانیم کنترل کننده هایی را که قبلاً تعریف کرده ایم به مسیرهای مختلف جفت کنیم. فراموش نکنید که به کنترل کننده وبلاگ نیاز دارید. بیا یک نگاهی بیندازیم:

const blogController = require('../controller/blogs');

const routes = [{
        method: 'GET',
        url: '/api/blogs',
        handler: blogController.getAllBlogs
    },
    {
        method: 'GET',
        url: '/api/blogs/:id',
        handler: blogController.getBlog
    },
    {
        method: 'POST',
        url: '/api/blogs',
        handler: blogController.addBlog
    },
    {
        method: 'PUT',
        url: '/api/blogs/:id',
        handler: blogController.updateBlog
    },
    {
        method: 'DELETE',
        url: '/api/blogs/:id',
        handler: blogController.deleteBlog
    }
]
module.exports = routes

اکنون همه مسیرها را مشخص کرده ایم. با این حال ، Fastify از این مسیرها اطلاعی ندارد. مرحله بعدی نشان می دهد که چگونه می توانید مسیرها را با آبجکت برنامه Fastify خود ثبت کنید.

مرحله 2.3: ثبت مسیرهای سریع

در این مرحله ، مسیرهای Fastify را به سمت شی app برنامه ثبت خواهیم کرد. ابتدا همه مسیرهای وبلاگ را بارگیری می کنیم. بعد ، ما تمام مسیرها را حلقه می کنیم تا آنها را یکی یکی ثبت کنیم:


const app = require('fastify')({
    logger: true
})


app.get("https://www.sitepoint.com/", function (req, reply) {
    reply.send({ hello: 'world' })
})


const blogRoutes = require('./routes/blogs')
blogRoutes.forEach((route, index) => {
    app.route(route)
})


app.listen(3000, (err, address) => {
    if (err) {
        app.log.error(err)
        process.exit(1)
    }
    app.log.info(`server listening on ${address}`)
})

انجام شده؟ وقت آن است که اعتبار مسیرهای وبلاگ را تأیید کنیم. چرخش سرور با استفاده از node index.js و بازدید http://localhost:3000/blogs/1 برای بدست آوردن اولین وبلاگ از داده های نسخه ی نمایشی. شما باید نتیجه زیر را ببینید:

{
    "id": 1,
    "title": "This is an experiment"
}

همه خوبند؟ بیایید در مرحله 3 بیاموزیم که چگونه اعتبار سنجی طرحها را به درخواستها و پاسخها اضافه کنیم.

مرحله 3: افزودن اعتبار سنجی طرحواره

این مرحله به شما می آموزد که چگونه اعتبار سنجی طرح را به پروژه خود اضافه کنید. ما می توانیم از schema کلید ماست routes تعریف برای انتقال یک طرح اعتبار سنجی به یک مسیر خاص.

بیایید با تعریف یک طرحواره برای مسیر شروع کنیم /api/blogs/:id برای تأیید اعتبار پارامتر و پاسخ درخواست. الزامات؟

  1. :id پارامتر باید از نوع رشته باشد
  2. پاسخ باید شامل یک شی با دو ویژگی باشد id (عدد صحیح) و title (رشته)

اعتبار سنجی زیر را به مورد خود اضافه کنید routes/blogs.js فایل:

const getBlogValidation = {
        params: {
            id: { type: 'string' }
        },
        response: {
            200: {
                type: 'object',
                properties: {
                    id: { type: 'integer' },
                    title: { type: 'string' }
                }
            }
        }
}

برای اتصال شی اعتبارسنجی به مسیر خود ، باید کلید طرح را تعریف کنیم. به دنبال /api/blogs/:id مسیر در routes آرایه را تغییر دهید و متناسب با آن تغییر دهید:

...
{
    method: 'GET',
    url: '/api/blogs/:id',
    schema: getBlogValidation, 
    handler: blogController.getBlog
},
...

بیایید همین کار را برای اضافه کردن یک وبلاگ انجام دهیم POST /api/blogs. در اینجا ، ما می خواهیم بررسی کنیم که آیا req.body شی شامل یک title پارامتر. بیا یک نگاهی بیندازیم:

const addBlogValidation = {
    body: {
        type: 'object',
        required: [
            'title'
        ],
        properties: {
            title: { type: 'string' }
        }
    },
    response: {
        200: {
            type: 'object',
            properties: {
                id: { type: 'integer' },
                title: { type: 'string' }
            }
        }
    }
}

در مرحله بعدی ، ما باید شی اعتبارسنجی را دوباره به مسیر صحیح متصل کنیم:

...
{
    method: 'POST',
    url: '/api/blogs',
    schema: addBlogValidation, 
    handler: blogController.addBlog
},
...

برای تأیید اعتبار ما ، وبلاگ را با شناسه 3 بازیابی کنیم. مرورگر خود را در اینجا باز کنید http://localhost:3000/api/blogs/3. باید پاسخ زیر را مشاهده کنید:

{
    "id": 3,
    "title": "Just another blog, yea!"
}

حالا ، بیایید اشتباه کنیم و params اعتبار سنجی برای id زمینه از sting به object مانند این:

const getBlogValidation = {
        params: {
            id: { type: 'object' } 
        },
        response: {
            200: {
                type: 'object',
                properties: {
                    id: { type: 'integer' },
                    title: { type: 'string' }
                }
            }
        }
}

هنگام درخواست همان منبع از API خود ، پیام خطای زیر را دریافت خواهید کرد.

{
    "statusCode": 400,
    "error": "Bad Request",
    "message": "params.id should be object"
}

آیا خطا را مشاهده می کنید؟ خوبه بیایید تغییر را به حالت اولیه برگردانیم string برای جلوگیری از خطاهای آینده و رفتن به مرحله بعدی.

مرحله 4: پلاگین های Fastify را بارگیری کنید

در اینجا ، بیایید از Fastify’s rich استفاده کنیم اکوسیستم پلاگین. می توانید افزونه هایی را پیدا کنید که در انجام کارهای مختلف مانند ادغام پایگاه داده یا تنظیمات مجوز به شما کمک می کنند. چرا می توانید وقت خود را برای نوشتن مجوز از ابتدا صرف کنید در حالی که می توانید از پلاگین های Fastify استفاده کنید؟ غالباً ، می خواهید به دنبال بسته هایی خارج از اکوسیستم Fastify باشید که در انجام برخی مشکلات یا وظایف به شما کمک کنند. با این حال ، با ارائه یک اکوسیستم پلاگین غنی ، Fastify به یک راه حل یک مرحله ای تبدیل می شود که قطعاً تجربه توسعه دهنده را بهبود می بخشد!

یک یادداشت سریع در مورد پلاگین ها: می توانید افزونه های خود را برای محصور کردن قابلیت ها ایجاد کنید. علاوه بر این ، می توانید آن پلاگین ها را در برنامه Fastify خود بارگذاری کنید. به طور پیش فرض ، Fastify خواهد شد ابتدا پلاگین ها را از اکوسیستم Fastify بارگیری کنید. پس از آن ، پلاگین های سفارشی بارگیری می شوند.

خوب ، بیایید عملی شویم! من می خواهم از fastify-env پلاگین ، که به شما در بارگیری متغیرهای محیط و تنظیم پیش فرض برای هر متغیر کمک می کند. بنابراین ، بیایید این وابستگی را به پروژه خود اضافه کنیم:

npm install --save fastify-env

بعد ، ما می توانیم بعد از بارگذاری شی application برنامه Fastify ، وابستگی را بارگیری کنیم index.js فایل. شما index.js پرونده به این شکل است:


const app = require('fastify')({
    logger: true
})


const fastifyEnv = require('fastify-env') 

const options = {
    confKey: 'config', 
    schema: {
        type: 'object',
        required: ['PORT'],
        properties: {
            PORT: {
                type: 'string',
                default: 1000
            }
        }
    }
}

app
    .register(fastifyEnv, options)
    .ready((err) => {
        if (err) console.error(err)

        console.log(app.config)
        
    })


app.get("https://www.sitepoint.com/", function (req, reply) {
    reply.send({ hello: 'world' })
})


const blogRoutes = require('./routes/blogs')
blogRoutes.forEach((route, index) => {
    app.route(route)
})


app.listen(app.config.PORT, (err, address) => {
    if (err) {
        app.log.error(err)
        process.exit(1)
    }
    app.log.info(`server listening on ${address}`)
})

توجه داشته باشید که ما باید یک تعریف کنیم options شی ای که به پلاگین fastify-env می گوید متغیرهای env را برای چه کاری جستجو کنید و به طور پیش فرض تنظیم کنید. در اینجا ، می خواهم a را بارگیری کنم PORT متغیر با مقدار پیش فرض 1000.

به طور پیش فرض ، پلاگین fastify-env همه متغیرهای محیط را از طریق شی app برنامه Fastify در دسترس قرار می دهد: app.config.PORT. چرا؟ افزونه fastify-env پیکربندیهای بارگیری شده را به confKey، که به طور پیش فرض روی آن تنظیم شده است config. با این حال ، در صورت تمایل ، می توانید این کلید را به کلید دیگری تغییر دهید.

پروژه را با شروع کنید node index.js و خروجی را کنترل کنید. شما باید ببینید PORT متغیری که در ترمینال شما چاپ می شود.

پلاگین های جالب دیگری برای استفاده وجود دارد؟

  1. تحقق بخشیدن به: چندین عملکرد auth را در Fastify اجرا کنید
  2. تحقق بخشیدن به حامل: bearer auth plugin for Fastify
  3. ذخیره سریع: پشتیبانی کلی از حافظه نهان و سرور سمت سرور
  4. کورس کردن: استفاده از CORS را در یک برنامه Fastify امکان پذیر می کند

مرحله 5: هوک ها را تعریف کنید

در آخر ، بیایید چند قلاب را تعریف کنیم. از مستندات قلاب را سریعتر انجام دهید، می توانیم موارد زیر را بخوانیم. “قلاب ها با روش fastify.addHook ثبت می شوند و به شما امکان گوش دادن به وقایع خاص در برنامه یا چرخه عمر درخواست / پاسخ را می دهند. شما باید قبل از شروع رویداد یک قلاب ثبت کنید ، در غیر این صورت این رویداد از دست می رود. “

قبل از تعیین مسیرها ، حتما قلاب ها را مشخص کنید:


app.addHook('onRoute', (routeOptions) => {
    console.log(`Registered route: ${routeOptions.url}`)
})


app.get("https://www.sitepoint.com/", function (req, reply) {
    reply.send({ hello: 'world' })
})

همانطور که می بینید ، addHook تابع ابتدا قلابی را که می خواهید برای آن گوش دهید قبول می کند. در مثال ما ، ما می خواهیم برای مسیرهای جدیدی که در برنامه ثبت شده اند گوش دهیم. در مرحله بعدی ، عملکرد برگشت پاسخ a را می پذیرد routeOptions آرگومان شامل اطلاعات زیادی مانند URL مسیر یا روش مسیر است.

جزئیات خاص برای onRoute قلاب را می توان در اسناد یافت.

بیایید API را با شروع کنیم node index.js تا ببینید کدام مسیرها ثبت شده اند. خروجی ترمینال شما باید به این شکل باشد:

Registered route: /
Registered route: /api/blogs
Registered route: /api/blogs/:id
Registered route: /api/blogs
Registered route: /api/blogs/:id
Registered route: /api/blogs/:id

همان خروجی را گرفتید؟ موفق باشید! در همان زمان ، این پایان آموزش Fastify بود. بیایید این پروژه را با یک نتیجه گیری کوتاه جمع بندی کنیم.

بسته بندی کردن

Fastify یک پروژه بسیار سبک وزن است که به شما امکان می دهد از اکوسیستم پلاگین غنی آن استفاده کنید. به جای ایجاد قابلیت از ابتدا ، می توانید از پلاگین های موجود استفاده کنید. به عبارت دیگر ، Fastify به عنوان یک فروشگاه یک مرحله ای برای توسعه دهندگان عمل می کند و به طور قطع تجربه توسعه دهنده را بهبود می بخشد.

من شخصاً از قابلیت Fastify hooks خوشم می آید زیرا می توانید برای برنامه های مختلف چرخه زندگی در برنامه خود گوش دهید.

برای کسب اطلاعات بیشتر در مورد Fastify ، صفحات اسناد زیر را بررسی کنید:

همچنین می توانید از repo برای این مقدمه در GitHub.