తెలుగు

Next.js రూట్ హ్యాండ్లర్లను ఉపయోగించి శక్తివంతమైన API ఎండ్‌పాయింట్లను ఎలా సృష్టించాలో తెలుసుకోండి. ఈ గైడ్ ప్రాథమిక సెటప్ నుండి అధునాతన టెక్నిక్‌ల వరకు, ప్రాక్టికల్ ఉదాహరణలు మరియు ఉత్తమ పద్ధతులతో అన్నింటినీ కవర్ చేస్తుంది.

Next.js రూట్ హ్యాండ్లర్లు: API ఎండ్‌పాయింట్ క్రియేషన్‌కు ఒక సమగ్ర మార్గదర్శి

Next.js దాని సర్వర్-సైడ్ రెండరింగ్, స్టాటిక్ సైట్ జనరేషన్ మరియు ఇప్పుడు, రూట్ హ్యాండ్లర్లు వంటి శక్తివంతమైన ఫీచర్లతో మనం వెబ్ అప్లికేషన్‌లను నిర్మించే విధానంలో విప్లవాత్మక మార్పులు తెచ్చింది. రూట్ హ్యాండ్లర్లు మీ Next.js అప్లికేషన్‌లో నేరుగా API ఎండ్‌పాయింట్‌లను సృష్టించడానికి ఒక సరళమైన మరియు సమర్థవంతమైన మార్గాన్ని అందిస్తాయి. ఈ గైడ్ రూట్ హ్యాండ్లర్ల భావన, వాటి ప్రయోజనాలు మరియు దృఢమైన APIలను నిర్మించడానికి వాటిని ఎలా సమర్థవంతంగా ఉపయోగించాలో వివరిస్తుంది.

Next.js రూట్ హ్యాండ్లర్లు అంటే ఏమిటి?

రూట్ హ్యాండ్లర్లు అనేవి Next.js ప్రాజెక్ట్ యొక్క app డైరెక్టరీలో నిర్వచించబడిన ఫంక్షన్లు, ఇవి ఇన్‌కమింగ్ HTTP అభ్యర్థనలను నిర్వహిస్తాయి. పాత pages/api విధానం (ఇది API రూట్లను ఉపయోగిస్తుంది) వలె కాకుండా, రూట్ హ్యాండ్లర్లు మీ రియాక్ట్ కాంపోనెంట్‌లతో పాటు API ఎండ్‌పాయింట్‌లను నిర్వచించడానికి మరింత క్రమబద్ధమైన మరియు సరళమైన మార్గాన్ని అందిస్తాయి. ఇవి ప్రాథమికంగా ఎడ్జ్ లేదా మీరు ఎంచుకున్న సర్వర్ వాతావరణంలో అమలు చేయబడే సర్వర్‌లెస్ ఫంక్షన్లు.

రూట్ హ్యాండ్లర్లను మీ Next.js అప్లికేషన్ యొక్క బ్యాకెండ్ లాజిక్‌గా భావించండి, ఇవి అభ్యర్థనలను ప్రాసెస్ చేయడానికి, డేటాబేస్‌లతో సంభాషించడానికి మరియు ప్రతిస్పందనలను తిరిగి ఇవ్వడానికి బాధ్యత వహిస్తాయి.

రూట్ హ్యాండ్లర్లను ఉపయోగించడం వల్ల కలిగే ప్రయోజనాలు

మీ Next.js ప్రాజెక్ట్‌ను సెటప్ చేయడం

రూట్ హ్యాండ్లర్లలోకి వెళ్లే ముందు, మీరు app డైరెక్టరీతో ఒక Next.js ప్రాజెక్ట్‌ను సెటప్ చేశారని నిర్ధారించుకోండి. మీరు కొత్త ప్రాజెక్ట్‌ను ప్రారంభిస్తుంటే, కింది కమాండ్‌ను ఉపయోగించండి:

npx create-next-app@latest my-nextjs-app

కొత్త రూటింగ్ సిస్టమ్‌ను ఎనేబుల్ చేయడానికి సెటప్ ప్రక్రియలో app డైరెక్టరీని ఎంచుకోండి.

మీ మొదటి రూట్ హ్యాండ్లర్‌ను సృష్టించడం

ఒక JSON ప్రతిస్పందనను తిరిగి ఇచ్చే ఒక సాధారణ API ఎండ్‌పాయింట్‌ను క్రియేట్ చేద్దాం. app డైరెక్టరీలో ఒక కొత్త డైరెక్టరీని, ఉదాహరణకు, /app/api/helloని సృష్టించండి. ఈ డైరెక్టరీ లోపల, route.ts (లేదా మీరు టైప్‌స్క్రిప్ట్ ఉపయోగించకపోతే route.js) అనే ఫైల్‌ను సృష్టించండి.

మీ మొదటి రూట్ హ్యాండ్లర్ కోసం కోడ్ ఇక్కడ ఉంది:

// app/api/hello/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Hello from Next.js Route Handlers!' });
}

వివరణ:

ఇప్పుడు, మీరు మీ బ్రౌజర్‌లో /api/helloకి నావిగేట్ చేయడం ద్వారా లేదా curl లేదా Postman వంటి సాధనాన్ని ఉపయోగించడం ద్వారా ఈ ఎండ్‌పాయింట్‌ను యాక్సెస్ చేయవచ్చు.

వివిధ HTTP పద్ధతులను నిర్వహించడం

రూట్ హ్యాండ్లర్లు GET, POST, PUT, DELETE, PATCH, మరియు OPTIONS వంటి వివిధ HTTP పద్ధతులకు మద్దతు ఇస్తాయి. మీరు ఒకే route.ts ఫైల్‌లో ప్రతి పద్ధతికి ప్రత్యేక ఫంక్షన్లను నిర్వచించవచ్చు.

// app/api/users/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 // డేటాబేస్ నుండి అన్ని వినియోగదారులను తిరిగి పొందే లాజిక్
 const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // ఉదాహరణ డేటా
 return NextResponse.json(users);
}

export async function POST(request: Request) {
 const data = await request.json(); // రిక్వెస్ట్ బాడీని JSONగా పార్స్ చేయండి
 // 'data'ని ఉపయోగించి డేటాబేస్‌లో కొత్త వినియోగదారుని సృష్టించే లాజిక్
 const newUser = { id: 3, name: data.name, email: data.email }; // ఉదాహరణ
 return NextResponse.json(newUser, { status: 201 }); // కొత్త వినియోగదారుని 201 క్రియేటెడ్ స్టేటస్ కోడ్‌తో తిరిగి ఇవ్వండి
}

వివరణ:

రిక్వెస్ట్ డేటాను యాక్సెస్ చేయడం

request ఆబ్జెక్ట్ ఇన్‌కమింగ్ రిక్వెస్ట్ గురించిన వివిధ సమాచారానికి, హెడర్‌లు, క్వెరీ పారామీటర్‌లు మరియు రిక్వెస్ట్ బాడీతో సహా యాక్సెస్‌ను అందిస్తుంది.

హెడర్లు

మీరు request.headers ప్రాపర్టీని ఉపయోగించి రిక్వెస్ట్ హెడర్‌లను యాక్సెస్ చేయవచ్చు:

export async function GET(request: Request) {
 const userAgent = request.headers.get('user-agent');
 console.log('User Agent:', userAgent);
 return NextResponse.json({ userAgent });
}

క్వెరీ పారామీటర్లు

క్వెరీ పారామీటర్‌లను యాక్సెస్ చేయడానికి, మీరు URL కన్‌స్ట్రక్టర్‌ను ఉపయోగించవచ్చు:

export async function GET(request: Request) {
 const url = new URL(request.url);
 const searchParams = new URLSearchParams(url.search);
 const id = searchParams.get('id');
 console.log('ID:', id);
 return NextResponse.json({ id });
}

రిక్వెస్ట్ బాడీ

POST, PUT, మరియు PATCH అభ్యర్థనల కోసం, కంటెంట్ రకాన్ని బట్టి మీరు request.json() లేదా request.text() పద్ధతులను ఉపయోగించి రిక్వెస్ట్ బాడీని యాక్సెస్ చేయవచ్చు.

export async function POST(request: Request) {
 const data = await request.json();
 console.log('Data:', data);
 return NextResponse.json({ receivedData: data });
}

ప్రతిస్పందనలను తిరిగి ఇవ్వడం

NextResponse ఆబ్జెక్ట్ API ప్రతిస్పందనలను నిర్మించడానికి ఉపయోగించబడుతుంది. ఇది హెడర్‌లు, స్టేటస్ కోడ్‌లు మరియు ప్రతిస్పందన బాడీలను సెట్ చేయడానికి అనేక పద్ధతులను అందిస్తుంది.

JSON ప్రతిస్పందనలు

JSON ప్రతిస్పందనలను తిరిగి ఇవ్వడానికి NextResponse.json() పద్ధతిని ఉపయోగించండి:

return NextResponse.json({ message: 'Success!', data: { name: 'John Doe' } }, { status: 200 });

టెక్స్ట్ ప్రతిస్పందనలు

ప్లెయిన్ టెక్స్ట్ ప్రతిస్పందనలను తిరిగి ఇవ్వడానికి new Response() కన్‌స్ట్రక్టర్‌ను ఉపయోగించండి:

return new Response('Hello, world!', { status: 200, headers: { 'Content-Type': 'text/plain' } });

రీడైరెక్ట్‌లు

వినియోగదారులను వేరే URLకి రీడైరెక్ట్ చేయడానికి NextResponse.redirect()ని ఉపయోగించండి:

import { redirect } from 'next/navigation';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.redirect(new URL('/new-location', request.url));
}

హెడర్లను సెట్ చేయడం

మీరు NextResponse.json() లేదా new Response()లో headers ఎంపికను ఉపయోగించి కస్టమ్ హెడర్‌లను సెట్ చేయవచ్చు:

return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });

మిడిల్‌వేర్ ఇంటిగ్రేషన్

మిడిల్‌వేర్ మీ రూట్ హ్యాండ్లర్ ద్వారా ఒక అభ్యర్థనను నిర్వహించడానికి ముందు కోడ్‌ను అమలు చేయడానికి మిమ్మల్ని అనుమతిస్తుంది. ఇది అథెంటికేషన్, ఆథరైజేషన్, లాగింగ్ మరియు ఇతర క్రాస్-కటింగ్ కన్సర్న్స్‌కు ఉపయోగపడుతుంది.

మిడిల్‌వేర్‌ను సృష్టించడానికి, app డైరెక్టరీలో లేదా ఏదైనా సబ్ డైరెక్టరీలో middleware.ts (లేదా middleware.js) అనే ఫైల్‌ను సృష్టించండి. మిడిల్‌వేర్ ఆ డైరెక్టరీ మరియు దాని సబ్ డైరెక్టరీలలోని అన్ని రూట్‌లకు వర్తిస్తుంది.

// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth-token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url));
 }

 return NextResponse.next();
}

export const config = {
 matcher: ['/protected/:path*'], // ఈ మిడిల్‌వేర్‌ను /protected/ తో ప్రారంభమయ్యే పాత్‌లకు వర్తింపజేయండి
};

వివరణ:

ఎర్రర్ హ్యాండ్లింగ్

దృఢమైన APIలను నిర్మించడానికి సరైన ఎర్రర్ హ్యాండ్లింగ్ చాలా ముఖ్యం. మినహాయింపులను నిర్వహించడానికి మరియు తగిన ఎర్రర్ ప్రతిస్పందనలను తిరిగి ఇవ్వడానికి మీరు try...catch బ్లాక్‌లను ఉపయోగించవచ్చు.

export async function GET(request: Request) {
 try {
 // ఒక ఎర్రర్‌ను అనుకరించండి
 throw new Error('Something went wrong!');
 } catch (error: any) {
 console.error('Error:', error);
 return NextResponse.json({ error: error.message }, { status: 500 });
 }
}

వివరణ:

స్ట్రీమింగ్ ప్రతిస్పందనలు

రూట్ హ్యాండ్లర్లు స్ట్రీమింగ్ ప్రతిస్పందనలకు మద్దతు ఇస్తాయి, ఇది క్లయింట్‌కు డేటాను క్రమంగా పంపడానికి మిమ్మల్ని అనుమతిస్తుంది. ఇది ప్రత్యేకంగా పెద్ద డేటాసెట్‌లు లేదా దీర్ఘకాలిక ప్రక్రియలకు ఉపయోగపడుతుంది.

import { Readable } from 'stream';
import { NextResponse } from 'next/server';

async function* generateData() {
 for (let i = 0; i < 10; i++) {
 await new Promise(resolve => setTimeout(resolve, 500)); // ఆలస్యాన్ని అనుకరించండి
 yield `Data chunk ${i}\n`;
 }
}

export async function GET(request: Request) {
 const readableStream = Readable.from(generateData());

 return new Response(readableStream, {
 headers: { 'Content-Type': 'text/plain; charset=utf-8' },
 });
}

వివరణ:

అథెంటికేషన్ మరియు ఆథరైజేషన్

మీ API ఎండ్‌పాయింట్‌లను సురక్షితంగా ఉంచడం చాలా ముఖ్యం. మీరు మిడిల్‌వేర్‌ను ఉపయోగించి లేదా నేరుగా మీ రూట్ హ్యాండ్లర్లలో అథెంటికేషన్ మరియు ఆథరైజేషన్‌ను అమలు చేయవచ్చు.

అథెంటికేషన్

అథెంటికేషన్ అభ్యర్థన చేస్తున్న వినియోగదారు యొక్క గుర్తింపును ధృవీకరిస్తుంది. సాధారణ అథెంటికేషన్ పద్ధతులు:

మిడిల్‌వేర్‌ను ఉపయోగించి JWT అథెంటికేషన్ యొక్క ఉదాహరణ ఇక్కడ ఉంది:

// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import jwt from 'jsonwebtoken';

const secret = process.env.JWT_SECRET || 'your-secret-key'; // బలమైన, యాదృచ్ఛికంగా ఉత్పత్తి చేయబడిన రహస్యంతో భర్తీ చేయండి

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth-token')?.value;

 if (!token) {
 return NextResponse.json({ message: 'Authentication required' }, { status: 401 });
 }

 try {
 jwt.verify(token, secret);
 return NextResponse.next();
 } catch (error) {
 return NextResponse.json({ message: 'Invalid token' }, { status: 401 });
 }
}

export const config = {
 matcher: ['/api/protected/:path*'],
};

ఆథరైజేషన్

ఆథరైజేషన్ ఒక వినియోగదారు ఏ వనరులను యాక్సెస్ చేయడానికి అనుమతించబడ్డాడో నిర్ణయిస్తుంది. ఇది సాధారణంగా పాత్రలు లేదా అనుమతులపై ఆధారపడి ఉంటుంది.

మీరు మీ రూట్ హ్యాండ్లర్లలో వినియోగదారు పాత్రలు లేదా అనుమతులను తనిఖీ చేయడం ద్వారా మరియు వారికి యాక్సెస్ లేకపోతే ఎర్రర్‌ను తిరిగి ఇవ్వడం ద్వారా ఆథరైజేషన్‌ను అమలు చేయవచ్చు.

// app/api/admin/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 // టోకెన్ లేదా సెషన్ నుండి వినియోగదారు పాత్రను పొందడానికి మీకు ఒక ఫంక్షన్ ఉందని అనుకుందాం
 const userRole = await getUserRole(request);

 if (userRole !== 'admin') {
 return NextResponse.json({ message: 'Unauthorized' }, { status: 403 });
 }

 // అడ్మిన్ డేటాను తిరిగి పొందే లాజిక్
 const adminData = { message: 'Admin data' };
 return NextResponse.json(adminData);
}

async function getUserRole(request: Request): Promise {
 // అభ్యర్థన నుండి వినియోగదారు పాత్రను సంగ్రహించడానికి మీ వాస్తవ లాజిక్‌తో భర్తీ చేయండి
 // దీనిలో JWT టోకెన్‌ను ధృవీకరించడం లేదా సెషన్‌ను తనిఖీ చేయడం ఉండవచ్చు
 return 'admin'; // ఉదాహరణ: ప్రదర్శన కోసం హార్డ్‌కోడ్ చేయబడిన పాత్ర
}

రూట్ హ్యాండ్లర్లను డిప్లాయ్ చేయడం

రూట్ హ్యాండ్లర్లు మీరు ఎంచుకున్న హోస్టింగ్ ప్రొవైడర్‌లో సర్వర్‌లెస్ ఫంక్షన్లుగా డిప్లాయ్ చేయబడతాయి. Next.js Vercel, Netlify, AWS, మరియు మరిన్ని వంటి వివిధ డిప్లాయ్‌మెంట్ ప్లాట్‌ఫారమ్‌లకు మద్దతు ఇస్తుంది.

Vercel కోసం, మీ Git రిపోజిటరీని Vercelకు కనెక్ట్ చేసి, మీ కోడ్‌ను పుష్ చేయడం అంత సులభం. Vercel స్వయంచాలకంగా మీ Next.js ప్రాజెక్ట్‌ను గుర్తించి, మీ రూట్ హ్యాండ్లర్లను సర్వర్‌లెస్ ఫంక్షన్లుగా డిప్లాయ్ చేస్తుంది.

అధునాతన టెక్నిక్‌లు

ఎడ్జ్ ఫంక్షన్లు

రూట్ హ్యాండ్లర్లను ఎడ్జ్ ఫంక్షన్లుగా డిప్లాయ్ చేయవచ్చు, ఇవి CDN యొక్క అంచున, మీ వినియోగదారులకు దగ్గరగా అమలు చేయబడతాయి. ఇది లేటెన్సీని గణనీయంగా తగ్గించి, పనితీరును మెరుగుపరుస్తుంది.

ఒక రూట్ హ్యాండ్లర్‌ను ఎడ్జ్ ఫంక్షన్‌గా డిప్లాయ్ చేయడానికి, మీ route.ts ఫైల్‌కు edge రన్‌టైమ్‌ను జోడించండి:

export const runtime = 'edge';

import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Hello from the Edge!' });
}

సర్వర్ యాక్షన్స్

సర్వర్ యాక్షన్స్ మీ రియాక్ట్ కాంపోనెంట్‌ల నుండి నేరుగా సర్వర్-సైడ్ కోడ్‌ను అమలు చేయడానికి మిమ్మల్ని అనుమతిస్తాయి. రూట్ హ్యాండ్లర్లు మరియు సర్వర్ యాక్షన్స్ కలిసి సజావుగా పనిచేస్తాయి, సంక్లిష్టమైన అప్లికేషన్‌లను సులభంగా నిర్మించడానికి మిమ్మల్ని అనుమతిస్తాయి.

ఒక రూట్ హ్యాండ్లర్‌ను కాల్ చేయడానికి సర్వర్ యాక్షన్‌ను ఉపయోగించే ఉదాహరణ ఇక్కడ ఉంది:

// app/components/MyComponent.tsx
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';

async function handleSubmit(data: FormData) {
 'use server';

 const name = data.get('name');
 const email = data.get('email');

 const response = await fetch('/api/users', {
 method: 'POST',
 body: JSON.stringify({ name, email }),
 });

 if (response.ok) {
 router.refresh(); // మార్పులను ప్రతిబింబించడానికి పేజీని రిఫ్రెష్ చేయండి
 }
}

export default function MyComponent() {
 const router = useRouter();

 return (
 




); }

క్యాచింగ్

క్యాచింగ్ మీ API ఎండ్‌పాయింట్‌ల పనితీరును గణనీయంగా మెరుగుపరుస్తుంది. బ్రౌజర్‌లు మరియు CDNల ద్వారా మీ ప్రతిస్పందనలు ఎలా కాష్ చేయబడతాయో నియంత్రించడానికి మీరు Cache-Control హెడర్‌ను ఉపయోగించవచ్చు.

return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });

ఈ ఉదాహరణ Cache-Control హెడర్‌ను public, max-age=3600కు సెట్ చేస్తుంది, ఇది బ్రౌజర్‌లు మరియు CDNలకు ఒక గంట పాటు ప్రతిస్పందనను కాష్ చేయమని చెబుతుంది.

ఉత్తమ పద్ధతులు

నిజ-ప్రపంచ ఉదాహరణలు

రూట్ హ్యాండ్లర్లను ఎలా ఉపయోగించవచ్చో కొన్ని నిజ-ప్రపంచ ఉదాహరణలు ఇక్కడ ఉన్నాయి:

అంతర్జాతీయ ఈ-కామర్స్ ఉదాహరణ: వినియోగదారు దేశం ఆధారంగా ఉత్పత్తి ధరలను తిరిగి పొందడానికి ఉపయోగించే ఒక రూట్ హ్యాండ్లర్. ఎండ్‌పాయింట్ వినియోగదారు యొక్క స్థానాన్ని నిర్ణయించడానికి రిక్వెస్ట్ యొక్క జియోలొకేషన్ (IP చిరునామా నుండి తీసుకోబడింది) ఉపయోగించి, తగిన కరెన్సీలో ధరలను తిరిగి ఇవ్వగలదు. ఇది స్థానికీకరించిన షాపింగ్ అనుభవానికి దోహదం చేస్తుంది.

గ్లోబల్ అథెంటికేషన్ ఉదాహరణ: ప్రపంచవ్యాప్తంగా వినియోగదారుల కోసం మల్టీ-ఫ్యాక్టర్ అథెంటికేషన్ (MFA)ను అమలు చేసే ఒక రూట్ హ్యాండ్లర్. దీనిలో SMS కోడ్‌లను పంపడం లేదా అథెంటికేటర్ యాప్‌లను ఉపయోగించడం ఉండవచ్చు, అదే సమయంలో వివిధ ప్రాంతాల గోప్యతా నిబంధనలు మరియు టెలికమ్యూనికేషన్ మౌలిక సదుపాయాలను గౌరవించడం జరుగుతుంది.

బహుభాషా కంటెంట్ డెలివరీ: వినియోగదారు ఇష్టపడే భాషలో కంటెంట్‌ను డెలివరీ చేసే ఒక రూట్ హ్యాండ్లర్. ఇది రిక్వెస్ట్‌లోని `Accept-Language` హెడర్ నుండి నిర్ణయించబడుతుంది. ఈ ఉదాహరణ సరైన UTF-8 ఎన్‌కోడింగ్ మరియు అవసరమైన చోట కుడి నుండి ఎడమకు భాషా మద్దతు యొక్క అవసరాన్ని హైలైట్ చేస్తుంది.

ముగింపు

Next.js రూట్ హ్యాండ్లర్లు మీ Next.js అప్లికేషన్‌లో నేరుగా API ఎండ్‌పాయింట్‌లను సృష్టించడానికి శక్తివంతమైన మరియు సరళమైన మార్గాన్ని అందిస్తాయి. రూట్ హ్యాండ్లర్లను ఉపయోగించడం ద్వారా, మీరు సులభంగా దృఢమైన APIలను నిర్మించవచ్చు, మీ బ్యాకెండ్ లాజిక్‌ను మీ రియాక్ట్ కాంపోనెంట్‌లతో కొలోకేట్ చేయవచ్చు మరియు మిడిల్‌వేర్, స్ట్రీమింగ్ మరియు ఎడ్జ్ ఫంక్షన్ల వంటి ఫీచర్ల ప్రయోజనాన్ని పొందవచ్చు.

ఈ సమగ్ర గైడ్ ప్రాథమిక సెటప్ నుండి అధునాతన టెక్నిక్‌ల వరకు అన్నింటినీ కవర్ చేసింది. ఈ గైడ్‌లో వివరించిన ఉత్తమ పద్ధతులను అనుసరించడం ద్వారా, మీరు సురక్షితమైన, పనితీరు గల మరియు నిర్వహించదగిన అధిక-నాణ్యత APIలను నిర్మించవచ్చు.