গ্রাফকিউএল (GraphQL)-এ File Upload একটি সাধারণ চ্যালেঞ্জ হতে পারে, কারণ গ্রাফকিউএল মূলত ডেটা কুয়েরি এবং ম্যানিপুলেশনের জন্য ডিজাইন করা হয়েছে, কিন্তু ফাইল আপলোডের জন্য সঠিক পদ্ধতি প্রয়োজন। যেহেতু গ্রাফকিউএল একটি সিঙ্ক্রোনাস (synchronous) প্রোটোকল নয় এবং ফাইলগুলি সাধারণত অনেক বড় হতে পারে, তাই ফাইল আপলোডের জন্য গ্রাফকিউএল কাস্টম সমাধান তৈরি করা প্রয়োজন।
তবে, Apollo Server এবং GraphQL Upload প্যাকেজের মাধ্যমে গ্রাফকিউএল-এ ফাইল আপলোড করা সম্ভব। এই প্যাকেজের মাধ্যমে আপনি ফাইল আপলোড করতে পারেন এবং সেই ফাইল ডেটা সার্ভারে পাঠাতে পারেন।
GraphQL এ File Upload এর প্রয়োজনীয়তা
- User-Generated Content: অনেক অ্যাপ্লিকেশন ব্যবহারকারী থেকে ছবি, ভিডিও বা ডকুমেন্ট সংগ্রহ করে। গ্রাফকিউএল-এর মাধ্যমে এই ফাইলগুলি নিরাপদে এবং সহজে সার্ভারে আপলোড করা যেতে পারে।
- Large File Handling: ফাইলগুলি সাধারণত বড় আকারের হয়, এবং তাদের হ্যান্ডলিংয়ের জন্য একটি বিশেষ পদ্ধতি প্রয়োজন। গ্রাফকিউএল-এ streaming বা multipart uploads সমর্থিত থাকলে এটি অনেক সুবিধাজনক হয়।
- Efficiency and Flexibility: একাধিক ফাইল বা বড় আকারের ফাইল গ্রাফকিউএল API-র মাধ্যমে আপলোড করার সময়, গ্রাফকিউএল তার স্কিমা ও রেজোলভারগুলির মাধ্যমে খুব সহজভাবে এই অপারেশনটি পরিচালনা করতে সাহায্য করে।
GraphQL এ File Upload এর পদ্ধতি
Apollo Server ব্যবহার করে ফাইল আপলোড করতে, GraphQL Upload প্যাকেজ ব্যবহার করা হয়। এই প্যাকেজটি ফাইল আপলোডের জন্য গ্রাফকিউএল স্কিমা এবং রেজোলভার পরিচালনা করতে সাহায্য করে।
ধাপ ১: প্রয়োজনীয় প্যাকেজগুলি ইন্সটল করা
প্রথমে, আপনি Apollo Server এবং graphql-upload প্যাকেজগুলি ইনস্টল করতে হবে:
npm install apollo-server graphql graphql-upload
ধাপ ২: Apollo Server সেটআপ করা
এখন, Apollo Server এবং ফাইল আপলোডের জন্য graphql-upload প্যাকেজ ব্যবহার করে সার্ভার সেটআপ করা হবে।
const { ApolloServer, gql } = require('apollo-server');
const { GraphQLUpload } = require('graphql-upload');
const path = require('path');
const fs = require('fs');
// GraphQL schema
const typeDefs = gql`
scalar Upload
type File {
filename: String!
mimetype: String!
encoding: String!
}
type Mutation {
singleUpload(file: Upload!): File!
}
`;
// Resolvers
const resolvers = {
Upload: GraphQLUpload, // This allows you to use Upload scalar type
Mutation: {
singleUpload: async (_, { file }) => {
const { createReadStream, filename, mimetype } = await file;
const stream = createReadStream();
const pathName = path.join(__dirname, '/uploads', filename);
// Writing file to the server's local disk
await new Promise((resolve, reject) =>
stream
.pipe(fs.createWriteStream(pathName))
.on('close', resolve)
.on('error', reject)
);
return { filename, mimetype, encoding: 'utf-8' }; // returning file details
},
},
};
// Apollo Server setup
const server = new ApolloServer({
typeDefs,
resolvers,
uploads: {
maxFileSize: 10000000, // 10 MB limit for file upload
maxFiles: 1, // Allow only 1 file upload at a time
},
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
এখানে:
- GraphQLUpload স্কেলার টাইপ হিসেবে ব্যবহার করা হয়েছে, যা ফাইল আপলোডের জন্য অনুমোদিত।
- singleUpload মিউটেশন ব্যবহারকারীকে একটি ফাইল আপলোড করার সুযোগ দেয়, এবং সার্ভারে সেই ফাইল সংরক্ষণ করা হয়।
ধাপ ৩: ক্লায়েন্ট সাইডে ফাইল আপলোড করা
ক্লায়েন্ট সাইডে, আপনি Apollo Client ব্যবহার করে ফাইল আপলোড করতে পারেন। এখানে, apollo-upload-client প্যাকেজটি ব্যবহার করা হবে।
প্রথমে, apollo-upload-client প্যাকেজটি ইনস্টল করুন:
npm install apollo-upload-client
এখন, ফাইল আপলোডের জন্য Apollo Client সেটআপ করুন:
import { ApolloClient, InMemoryCache, ApolloProvider, gql } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
import React, { useState } from 'react';
// Apollo Client setup
const client = new ApolloClient({
link: createUploadLink({ uri: 'http://localhost:4000' }), // Server URL
cache: new InMemoryCache(),
});
const UPLOAD_FILE = gql`
mutation singleUpload($file: Upload!) {
singleUpload(file: $file) {
filename
mimetype
encoding
}
}
`;
const FileUpload = () => {
const [file, setFile] = useState(null);
const handleFileChange = (e) => {
setFile(e.target.files[0]);
};
const handleUpload = async () => {
try {
const { data } = await client.mutate({
mutation: UPLOAD_FILE,
variables: { file },
});
console.log('File uploaded successfully:', data);
} catch (error) {
console.error('Error uploading file:', error);
}
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUpload}>Upload</button>
</div>
);
};
export default () => (
<ApolloProvider client={client}>
<FileUpload />
</ApolloProvider>
);
এখানে:
- createUploadLink ব্যবহার করা হয়েছে, যা Apollo Client-এর সাথে ফাইল আপলোড সংযোগ করতে সহায়ক।
- UPLOAD_FILE মিউটেশন ব্যবহার করে ফাইল সার্ভারে আপলোড করা হচ্ছে।
File Upload এর সীমাবদ্ধতা এবং সুরক্ষা
- File Size Limit:
ফাইলের আকার সীমাবদ্ধ করা উচিত, যাতে সার্ভার বেশি বড় ফাইল হ্যান্ডল করতে সক্ষম হয়। আপনি Apollo Server-এ maxFileSize ব্যবহার করে সীমা নির্ধারণ করতে পারেন। - Multiple File Upload:
যদি আপনি একাধিক ফাইল আপলোড করতে চান, তাহলে আপনি maxFiles প্যারামিটারটি ব্যবহার করে সেটি সীমাবদ্ধ করতে পারেন। অথবা, আপনি একাধিক ফাইল আপলোডের জন্য আলাদা কুয়েরি বা মিউটেশন তৈরি করতে পারেন। - Security Considerations:
ফাইল আপলোডের সময়, সুরক্ষা নিশ্চিত করতে হবে। যেমন, file type validation, file size validation, এবং content filtering করা উচিত। এভাবে আপনি malicious ফাইল আপলোডের ঝুঁকি কমাতে পারেন।
সারাংশ
GraphQL এ File Upload একটি শক্তিশালী ফিচার হতে পারে, যেখানে ব্যবহারকারীরা সহজেই বড় ফাইল আপলোড করতে পারে। Apollo Server এবং graphql-upload প্যাকেজ ব্যবহার করে আপনি সহজেই ফাইল আপলোড পরিচালনা করতে পারেন। ক্লায়েন্ট সাইডে Apollo Client ব্যবহার করে ফাইল আপলোড করা যায়, যা সহজ এবং কার্যকরী। তবে, ফাইল আপলোডের ক্ষেত্রে size, security, এবং multiple file handling সম্পর্কে সতর্ক থাকা উচিত।
গ্রাফকিউএল (GraphQL)-এ File এবং Image Upload একটি গুরুত্বপূর্ণ এবং সাধারণ ফিচার, যা ওয়েব অ্যাপ্লিকেশন এবং মোবাইল অ্যাপ্লিকেশনগুলিতে বিভিন্ন ধরনের ফাইল এবং চিত্র আপলোডের জন্য ব্যবহৃত হয়। গ্রাফকিউএল স্বাভাবিকভাবে স্ট্রাকচারড ডেটা প্রসেস করতে সক্ষম, তবে ফাইল এবং চিত্র আপলোডের জন্য অতিরিক্ত ব্যবস্থা নিতে হয়, কারণ গ্রাফকিউএল কেবল JSON ডেটা প্রক্রিয়া করতে ডিজাইন করা হয়েছে।
ফাইল এবং চিত্র আপলোডের জন্য, Apollo Server এর মতো গ্রাফকিউএল সার্ভার ব্যবহার করা হয়, এবং সাধারণত এটি multipart/form-data ইন্টারফেস ব্যবহার করে কাজ করে। এই ইন্টারফেস ফাইল আপলোডের জন্য বিশেষভাবে ডিজাইন করা হয়।
GraphQL এর মাধ্যমে File এবং Image Upload এর জন্য প্রয়োজনীয় টুলস
- Apollo Server - GraphQL সার্ভার ব্যবহারের জন্য।
- graphql-upload - ফাইল আপলোডের জন্য Apollo Server বা অন্য গ্রাফকিউএল সার্ভারে ব্যবহার করা হয়।
- Multer (নোডে) - ফাইল আপলোডের জন্য ব্যবহৃত সাধারণ লাইব্রেরি।
ধাপ ১: প্রয়োজনীয় প্যাকেজ ইন্সটল করা
প্রথমে, আপনার প্রজেক্টে Apollo Server, graphql-upload, এবং multer ইন্সটল করতে হবে।
npm install apollo-server graphql graphql-upload multer
ধাপ ২: File Upload এর জন্য GraphQL Schema তৈরি করা
GraphQL স্কিমাতে আমরা একটি Upload টাইপ এবং একটি mutation সংজ্ঞায়িত করব, যা ফাইল আপলোডের জন্য ব্যবহার করা হবে।
const { ApolloServer, gql } = require('apollo-server');
const { GraphQLUpload } = require('graphql-upload');
const path = require('path');
const fs = require('fs');
// GraphQL Schema
const typeDefs = gql`
scalar Upload
type File {
filename: String!
mimetype: String!
encoding: String!
path: String!
}
type Mutation {
singleUpload(file: Upload!): File!
}
`;
// Resolver to handle the file upload
const resolvers = {
Upload: GraphQLUpload,
Mutation: {
singleUpload: async (parent, { file }) => {
const { createReadStream, filename, mimetype, encoding } = await file;
const stream = createReadStream();
const pathName = path.join(__dirname, "/uploads", filename);
// Create a writable stream and save the file
const out = fs.createWriteStream(pathName);
stream.pipe(out);
await new Promise((resolve, reject) =>
out.on('finish', resolve).on('error', reject)
);
return {
filename,
mimetype,
encoding,
path: pathName,
};
},
},
};
// Apollo Server setup
const server = new ApolloServer({
typeDefs,
resolvers,
uploads: {
maxFileSize: 10000000, // 10 MB
maxFiles: 1, // Max 1 file
},
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
এখানে:
- Upload টাইপ ব্যবহার করা হয়েছে, যা graphql-upload লাইব্রেরি থেকে এসেছে এবং ফাইল আপলোডের জন্য গ্রাফকিউএল স্কিমায় ব্যবহার করা হয়।
- singleUpload মিউটেশন তৈরি করা হয়েছে, যা ফাইল আপলোড করার জন্য ব্যবহৃত হবে।
- ফাইলটি fs.createWriteStream ব্যবহার করে সঠিক লোকেশনে সংরক্ষণ করা হচ্ছে।
ধাপ ৩: ফাইল আপলোড করার জন্য Client-Side GraphQL Mutation তৈরি করা
এখন, ক্লায়েন্ট সাইডে একটি GraphQL Mutation তৈরি করতে হবে যা ফাইল আপলোড করবে। ফাইল আপলোড করার জন্য, Apollo Client ব্যবহার করা যেতে পারে।
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
// Apollo Client setup
const client = new ApolloClient({
link: createUploadLink({ uri: 'http://localhost:4000' }),
cache: new InMemoryCache(),
});
// File upload mutation
const UPLOAD_FILE = gql`
mutation uploadFile($file: Upload!) {
singleUpload(file: $file) {
filename
mimetype
encoding
path
}
}
`;
// File input element and upload handling
document.getElementById('uploadBtn').addEventListener('change', async (e) => {
const file = e.target.files[0];
try {
const { data } = await client.mutate({
mutation: UPLOAD_FILE,
variables: { file },
});
console.log('File uploaded successfully:', data.singleUpload);
} catch (error) {
console.error('Error uploading file:', error);
}
});
এখানে:
- createUploadLink ব্যবহার করা হয়েছে ফাইল আপলোডের জন্য, যা Apollo Client-কে GraphQL সার্ভারে ফাইল আপলোড করার অনুমতি দেয়।
- UPLOAD_FILE মিউটেশন তৈরি করা হয়েছে, যা ফাইল আপলোডের জন্য ব্যবহৃত হবে।
ধাপ ৪: Client-Side HTML ফাইল তৈরি করা
আপনার HTML ফাইলে একটি ফাইল ইনপুট বাটন এবং একটি সাবমিট বাটন থাকতে হবে যা ফাইল নির্বাচন করবে এবং সার্ভারে পাঠাবে।
<input type="file" id="uploadBtn" />
এখানে:
- uploadBtn হচ্ছে ফাইল ইনপুট এলিমেন্ট, যার মাধ্যমে ইউজার ফাইল নির্বাচন করবে।
ধাপ ৫: ফাইল আপলোডের জন্য সুরক্ষা এবং সীমাবদ্ধতা
ফাইল আপলোডের ক্ষেত্রে সুরক্ষা এবং সীমাবদ্ধতার বিষয়টি খুবই গুরুত্বপূর্ণ। এখানে কিছু সাধারণ সুরক্ষা ব্যবস্থা রয়েছে:
- ফাইল সাইজ সীমাবদ্ধ করা: আপনি আপলোডযোগ্য ফাইলের সাইজ সীমাবদ্ধ করতে পারেন, যেমন 10MB বা 20MB এর বেশি ফাইল আপলোড করা যাবে না।
- উদাহরণ:
maxFileSize: 10000000(10MB)
- উদাহরণ:
- ফাইল টাইপের বৈধতা যাচাই: আপলোডযোগ্য ফাইলের টাইপ যাচাই করা, যেমন শুধুমাত্র ছবি বা PDF আপলোডের অনুমতি দেওয়া যেতে পারে।
- প্রতিক্রিয়া এবং ত্রুটি হ্যান্ডলিং: সঠিকভাবে ত্রুটি হ্যান্ডলিং করা উচিত, যেমন ফাইল আপলোডের সময় যদি কোনো সমস্যা হয়, তাহলে ইউজারকে সঠিক ত্রুটি বার্তা দেখানো।
সারাংশ
GraphQL-এ File এবং Image Upload বাস্তবায়ন করতে Apollo Server এবং graphql-upload লাইব্রেরি ব্যবহার করা হয়। ফাইল আপলোডের জন্য GraphQL Mutation তৈরি করা হয়, যা ক্লায়েন্ট থেকে ফাইল গ্রহণ করে এবং সার্ভারে সেগুলি সংরক্ষণ করে। এটির মাধ্যমে আপনি সহজেই ফাইল এবং ছবি আপলোডের কার্যকারিতা আপনার অ্যাপ্লিকেশনে যোগ করতে পারবেন।
GraphQL-এ File Upload প্রক্রিয়া কিছুটা ভিন্ন, কারণ গ্রাফকিউএল ডিফল্টভাবে ফাইল হ্যান্ডলিং সমর্থন করে না। তবে, আপনি Scalar Type ব্যবহার করে গ্রাফকিউএল-এ ফাইল আপলোড পরিচালনা করতে পারেন। এখানে Scalar Type ব্যবহার করে ফাইল আপলোড করার প্রক্রিয়া ব্যাখ্যা করা হবে।
GraphQL File Upload Scalar Type
Scalar Types হল গ্রাফকিউএল-এ ডেটার মৌলিক ধরন (যেমন, String, Int, Float, Boolean, ID)। কিন্তু ফাইল আপলোডের জন্য গ্রাফকিউএল ডিফল্ট কোনও Scalar Type সরবরাহ করে না, তাই আমরা custom scalar type ব্যবহার করে ফাইল আপলোড পরিচালনা করতে পারি।
ফাইল আপলোডের জন্য গ্রাফকিউএল Upload নামক একটি বিশেষ Scalar Type ব্যবহার করে। এটি Apollo Server বা অন্য গ্রাফকিউএল সার্ভার ব্যবহার করার সময় ফাইল আপলোডের জন্য প্রয়োজনীয় পদ্ধতি সরবরাহ করে।
ফাইল আপলোডের জন্য Apollo Server Setup
ফাইল আপলোড করতে, আমরা Apollo Server এর সাথে graphql-upload প্যাকেজ ব্যবহার করতে পারি। এই প্যাকেজটি গ্রাফকিউএল-এ ফাইল আপলোডের জন্য Upload Scalar Type প্রদান করে এবং ফাইলটি সার্ভারে প্রসেস করার প্রক্রিয়া সহজ করে।
ধাপ ১: প্রয়োজনীয় প্যাকেজ ইনস্টল করা
প্রথমে, Apollo Server এবং graphql-upload প্যাকেজ দুটি ইন্সটল করতে হবে:
npm install apollo-server graphql graphql-upload
ধাপ ২: Apollo Server সেটআপ করা
এখন, Apollo Server এবং graphql-upload প্যাকেজ ব্যবহার করে একটি GraphQL সার্ভার তৈরি করুন যেখানে আমরা Upload Scalar Type ব্যবহার করব।
const { ApolloServer, gql } = require('apollo-server');
const { GraphQLUpload } = require('graphql-upload');
const path = require('path');
const fs = require('fs');
// Define GraphQL schema
const typeDefs = gql`
scalar Upload
type File {
filename: String
mimetype: String
encoding: String
}
type Mutation {
uploadFile(file: Upload!): File!
}
`;
// Define resolvers
const resolvers = {
Upload: GraphQLUpload,
Mutation: {
uploadFile: async (_, { file }) => {
const { createReadStream, filename, mimetype, encoding } = await file;
// Save the file to the server
const stream = createReadStream();
const out = fs.createWriteStream(path.join(__dirname, 'uploads', filename));
stream.pipe(out);
// Return file details
return { filename, mimetype, encoding };
},
},
};
// Create Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
uploads: {
maxFileSize: 10000000, // Maximum file size (10 MB)
maxFiles: 10, // Maximum number of files
},
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
কোড ব্যাখ্যা:
- Upload Scalar Type:
graphql-uploadপ্যাকেজটি একটিUploadScalar Type সরবরাহ করে, যা ফাইল আপলোডের জন্য ব্যবহৃত হয়। আমরা এটি আমাদের গ্রাফকিউএল স্কিমাতে সংজ্ঞায়িত করেছি।
- Mutation:
- আমরা একটি Mutation
uploadFileতৈরি করেছি যা ফাইল আপলোড গ্রহণ করে এবং সার্ভারে সেই ফাইলটি সংরক্ষণ করে।file: Upload!অ্যারগুমেন্টে ফাইল গ্রহণ করে এবং এর মধ্যে ডেটা থাকে যেমনcreateReadStream,filename,mimetype, এবংencoding।
- আমরা একটি Mutation
- File Saving:
createReadStreamফাংশনটি ফাইলের স্ট্রীম দেয় এবং আমরা সেটি 'uploads' ফোল্ডারে সংরক্ষণ করেছি।fs.createWriteStreamব্যবহার করে ফাইলটি লোকাল ফোল্ডারে সেভ করা হয়েছে।
- Upload Configuration:
- আপলোডের জন্য আমরা কিছু কনফিগারেশন সেট করেছি, যেমন maxFileSize (যা ১০MB পর্যন্ত সীমাবদ্ধ) এবং maxFiles (যা সর্বাধিক ১০টি ফাইল আপলোড করতে পারে)।
ধাপ ৩: ফাইল আপলোডের জন্য GraphQL কুয়েরি
এখন, আপনি একটি GraphQL Mutation ব্যবহার করে ফাইল আপলোড করতে পারবেন। একটি ক্লায়েন্ট ফাইল আপলোড করার জন্য নিচের মতো কুয়েরি করতে পারে:
mutation($file: Upload!) {
uploadFile(file: $file) {
filename
mimetype
encoding
}
}
এখানে:
$fileহল ফাইলের জন্য একটি variable যা ফাইল ডেটা গ্রহণ করে।- ফাইল আপলোডের পর, সার্ভার ফাইলের বিস্তারিত (যেমন
filename,mimetype,encoding) ফেরত পাঠায়।
ধাপ ৪: Apollo Client দিয়ে ফাইল আপলোড করা
আপনি Apollo Client ব্যবহার করে এই Mutation চালাতে পারেন। এখানে একটি উদাহরণ দেওয়া হলো কিভাবে ফাইল ক্লায়েন্ট সাইড থেকে আপলোড করা যাবে:
import { ApolloClient, InMemoryCache, gql, HttpLink } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
// Apollo Client Setup
const client = new ApolloClient({
link: createUploadLink({ uri: 'http://localhost:4000' }),
cache: new InMemoryCache(),
});
// GraphQL Mutation
const UPLOAD_FILE = gql`
mutation($file: Upload!) {
uploadFile(file: $file) {
filename
mimetype
encoding
}
}
`;
// File Upload Function
const uploadFile = async (file) => {
const { data } = await client.mutate({
mutation: UPLOAD_FILE,
variables: { file },
});
console.log(data.uploadFile);
};
// Example of using the file input
const fileInput = document.getElementById("fileInput");
fileInput.addEventListener("change", (e) => {
const file = e.target.files[0];
uploadFile(file);
});
এখানে:
- Apollo Client ব্যবহার করে গ্রাফকিউএল সার্ভারে ফাইল আপলোড করা হয়েছে।
createUploadLinkব্যবহার করা হয়েছে যাতে ফাইল আপলোড সঠিকভাবে হ্যান্ডল করা যায়।- ক্লায়েন্টের মাধ্যমে fileInput ব্যবহার করে ফাইল নির্বাচন করা হয় এবং পরে সেই ফাইলটি uploadFile ফাংশনের মাধ্যমে গ্রাফকিউএল সার্ভারে আপলোড করা হয়।
সারাংশ
গ্রাফকিউএল ফাইল আপলোডের জন্য Scalar Type ব্যবহার একটি শক্তিশালী উপায়, যেখানে Upload Scalar Type এবং graphql-upload প্যাকেজ ব্যবহার করে সহজেই ফাইল আপলোড পরিচালনা করা যায়। Apollo Server এবং Apollo Client এর মাধ্যমে গ্রাফকিউএল-এ ফাইল আপলোড করা সহজ এবং কার্যকরী।
Apollo Server এর মাধ্যমে Multiple File Upload পরিচালনা করার প্রক্রিয়া কিছুটা জটিল হতে পারে, কারণ গ্রাফকিউএল নিজে কোনো নির্দিষ্ট ফাইল আপলোড করার পদ্ধতি সরবরাহ করে না। তবে, Apollo Server এবং GraphQL ব্যবহার করে আপনি file upload ফিচার যুক্ত করতে পারেন। এর জন্য graphql-upload লাইব্রেরি ব্যবহার করা হয়, যা ফাইল আপলোডের জন্য প্রয়োজনীয় সরঞ্জাম প্রদান করে।
এখানে Apollo Server দিয়ে Multiple File Upload পরিচালনা করার ধাপে ধাপে গাইডলাইন দেওয়া হলো।
ধাপ ১: প্রয়োজনীয় প্যাকেজ ইন্সটল করা
প্রথমে, আমরা কিছু প্যাকেজ ইনস্টল করব যা ফাইল আপলোডের জন্য দরকার:
npm install apollo-server graphql graphql-upload
এখানে:
- graphql-upload: এটি ফাইল আপলোড করতে সাহায্য করে এবং Apollo Server এর সাথে ইন্টিগ্রেট করা যায়।
ধাপ ২: Apollo Server এবং File Upload Setup করা
আমরা Apollo Server এর মাধ্যমে ফাইল আপলোডের জন্য graphql-upload ব্যবহার করব। এখানে, আমরা একটি ফাইল আপলোড কুয়েরি এবং রেজোলভার তৈরি করব যা একাধিক ফাইল আপলোড গ্রহণ করবে।
- Apollo Server Setup:
const { ApolloServer, gql } = require('apollo-server');
const { GraphQLUpload, processRequest } = require('graphql-upload');
const path = require('path');
const fs = require('fs');
// GraphQL Schema
const typeDefs = gql`
scalar Upload
type File {
filename: String
mimetype: String
encoding: String
}
type Query {
hello: String
}
type Mutation {
uploadFiles(files: [Upload!]!): [File]
}
`;
// Resolvers for handling file upload
const resolvers = {
Upload: GraphQLUpload, // Set GraphQLUpload as the Upload scalar type
Query: {
hello: () => "Hello, world!",
},
Mutation: {
uploadFiles: async (_, { files }) => {
const fileData = await Promise.all(
files.map(async (file) => {
const { createReadStream, filename, mimetype, encoding } = await file;
// Create a write stream to save the file locally
const stream = createReadStream();
const pathName = path.join(__dirname, '/uploads', filename);
// Write file to disk
const out = fs.createWriteStream(pathName);
stream.pipe(out);
await new Promise((resolve, reject) => {
out.on('finish', resolve);
out.on('error', reject);
});
return { filename, mimetype, encoding };
})
);
return fileData;
},
},
};
// Apollo Server Configuration
const server = new ApolloServer({
typeDefs,
resolvers,
uploads: {
maxFileSize: 10000000, // Maximum file size (in bytes)
maxFiles: 10, // Maximum number of files that can be uploaded
},
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
এখানে:
- Upload Scalar:
Uploadটাইপ ব্যবহার করে, আমরা গ্রাফকিউএল স্কিমায় ফাইল আপলোডের জন্য একটি scalar টাইপ যুক্ত করছি। - uploadFiles Mutation: একাধিক ফাইল আপলোড করার জন্য একটি মিউটেশন তৈরি করা হয়েছে। এখানে, প্রতিটি ফাইলের তথ্য সংগ্রহ করা হচ্ছে (ফাইলের নাম, MIME টাইপ, ইত্যাদি) এবং লোকাল ডিস্কে সেই ফাইল সংরক্ষণ করা হচ্ছে।
ধাপ ৩: ফাইল আপলোড কুয়েরি (GraphQL Mutation)
এখন, আপনি GraphQL Mutation ব্যবহার করে একাধিক ফাইল আপলোড করতে পারবেন। এখানে একটি mutation উদাহরণ দেওয়া হলো:
mutation UploadFiles($files: [Upload!]!) {
uploadFiles(files: $files) {
filename
mimetype
encoding
}
}
এখানে:
$filesভেরিয়েবলটি Upload টাইপে ডেটা গ্রহণ করে, যা একাধিক ফাইল আপলোড করার জন্য ব্যবহৃত হবে।
কুয়েরি পাঠানোর উদাহরণ (GraphQL Client Example):
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
const client = new ApolloClient({
link: createUploadLink({ uri: 'http://localhost:4000' }),
cache: new InMemoryCache(),
});
const UPLOAD_FILES = gql`
mutation UploadFiles($files: [Upload!]!) {
uploadFiles(files: $files) {
filename
mimetype
encoding
}
}
`;
async function uploadFiles(files) {
try {
const { data } = await client.mutate({
mutation: UPLOAD_FILES,
variables: { files },
});
console.log(data.uploadFiles);
} catch (error) {
console.error('Error uploading files', error);
}
}
এখানে:
- createUploadLink ব্যবহার করে, Apollo Client-কে ফাইল আপলোডের জন্য কনফিগার করা হয়েছে।
ধাপ ৪: File Upload ফর্ম তৈরি করা (Frontend)
এখন, ফ্রন্টএন্ডে ফাইল আপলোড ফর্ম তৈরি করতে হবে। এখানে একটি সিম্পল HTML ফর্ম দেখানো হলো:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>GraphQL File Upload</title>
</head>
<body>
<form id="upload-form">
<input type="file" name="files" id="fileInput" multiple />
<button type="submit">Upload Files</button>
</form>
<script src="https://cdn.jsdelivr.net/npm/@apollo/client@3.5.8/core.js"></script>
<script>
document.getElementById('upload-form').addEventListener('submit', async (e) => {
e.preventDefault();
const files = document.getElementById('fileInput').files;
const fileArray = Array.from(files);
// Create a form data object to send the files
const formData = new FormData();
fileArray.forEach(file => {
formData.append('files', file);
});
// Send the files to the server via GraphQL mutation
await uploadFiles(fileArray); // Call the upload function defined earlier
});
</script>
</body>
</html>
এখানে:
- multiple attribute সহ ফাইল ইনপুট ব্যবহার করা হয়েছে, যাতে একাধিক ফাইল নির্বাচন করা যায়।
- ফর্ম সাবমিট হলে, uploadFiles মিউটেশন কল করা হচ্ছে যেটি ফাইলগুলো আপলোড করবে।
সারাংশ
Apollo Server এবং graphql-upload ব্যবহার করে Multiple File Upload পরিচালনা করা সম্ভব। আপনি ফাইলগুলো গ্রাফকিউএল Upload scalar টাইপের মাধ্যমে ক্লায়েন্ট থেকে সার্ভারে পাঠাতে পারেন, এবং সার্ভার সেই ফাইলগুলোকে ডিস্কে সেভ করে সঠিক ফর্ম্যাটে ডেটা ফেরত দিতে পারে। এই পদ্ধতিটি front-end এবং back-end এর মধ্যে সহজভাবে ফাইল আপলোড এবং ম্যানেজমেন্ট করার সুযোগ দেয়।
গ্রাফকিউএল (GraphQL) ফাইল আপলোড এবং ভ্যালিডেশন, বিশেষ করে নিরাপত্তা এবং ডেটা সুরক্ষা বিষয়গুলোকে সঠিকভাবে পরিচালনা করা গুরুত্বপূর্ণ। ফাইল আপলোড করা একটি সাধারণ কার্যকলাপ হলেও, এর সাথে সঠিক ভ্যালিডেশন এবং নিরাপত্তা ব্যবস্থা নিশ্চিত না করলে আপনার অ্যাপ্লিকেশন বিপদে পড়তে পারে। এখানে ফাইল আপলোডের জন্য গ্রাফকিউএল ব্যবহারে কিছু গুরুত্বপূর্ণ File Validation এবং Security Considerations তুলে ধরা হলো।
File Validation in GraphQL
ফাইল আপলোডের ক্ষেত্রে, GraphQL নিজে কোন বিল্ট-ইন ফাইল আপলোড ফিচার সরবরাহ না করলেও, আপনি একটি কাস্টম স্কিমা ব্যবহার করে ফাইল আপলোড সক্ষম করতে পারেন। ফাইল আপলোড করার জন্য Apollo Server এবং GraphQL Upload প্যাকেজ ব্যবহৃত হয়।
File Upload কিভাবে কাজ করে:
- ক্লায়েন্ট থেকে ফাইলটি একটি multipart/form-data রিকোয়েস্টের মাধ্যমে সার্ভারে পাঠানো হয়।
- গ্রাফকিউএল স্কিমার মাধ্যমে ফাইলটি Upload টাইপে রিসিভ করা হয়।
- ফাইলের জন্য সঠিক validation এবং storage ব্যবস্থা নিশ্চিত করা হয়।
File Upload এবং Validation এর প্রক্রিয়া
- GraphQL Upload প্যাকেজ ইন্সটল করা: গ্রাফকিউএল এ ফাইল আপলোডের জন্য graphql-upload প্যাকেজ ইন্সটল করতে হবে।
npm install graphql-upload
- GraphQL Schema এর মাধ্যমে ফাইল আপলোড:
scalar Upload
type Mutation {
singleUpload(file: Upload!): File
}
type File {
filename: String
mimetype: String
encoding: String
}
এখানে:
- Upload হল একটি বিশেষ scalar টাইপ যা ফাইল আপলোডের জন্য ব্যবহৃত হয়।
- singleUpload হল একটি মিউটেশন, যেখানে ফাইল আপলোড করা যাবে।
- Resolvers ব্যবহার করে ফাইল আপলোড করা:
const { GraphQLUpload } = require('graphql-upload');
const resolvers = {
Upload: GraphQLUpload,
Mutation: {
singleUpload: async (parent, { file }) => {
const { createReadStream, filename, mimetype, encoding } = await file;
// ফাইল স্টোরেজ বা ডেটাবেসে সেভ করার লজিক এখানে থাকবে
return { filename, mimetype, encoding };
},
},
};
এখানে:
- createReadStream ব্যবহার করে ফাইলের ডেটা পড়া হয় এবং filename, mimetype, encoding এর মতো মেটাডেটা পাওয়া যায়।
- ফাইলটি সঠিকভাবে ডাটাবেস বা ফাইল সিস্টেমে সংরক্ষণ করা যেতে পারে।
File Validation
ফাইলের নিরাপত্তা এবং সঠিকতা যাচাই করার জন্য কিছু ভ্যালিডেশন পদ্ধতি রয়েছে:
- File Size Validation: ফাইলের আকার খুব বড় হতে পারে, যা সার্ভারের স্টোরেজ বা নেটওয়ার্ক ট্রাফিকের ওপর চাপ ফেলতে পারে। তাই, ফাইলের আকার সীমাবদ্ধ করা উচিত।
if (file.size > MAX_FILE_SIZE) {
throw new Error('File size is too large');
}
- File Type Validation: ফাইলের টাইপ (mimetype) যাচাই করা গুরুত্বপূর্ণ, কারণ কিছু ফাইল এক্সটেনশন নিরাপদ নাও হতে পারে।
const allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf'];
if (!allowedMimeTypes.includes(file.mimetype)) {
throw new Error('Invalid file type');
}
- File Content Validation: ফাইলের কনটেন্ট নিরাপদ হওয়া প্রয়োজন। উদাহরণস্বরূপ, একটি image file যদি ম্যালওয়্যার ধারণ করে, তা হতে পারে বিপদজনক। এমন ধরনের ফাইলের জন্য অতিরিক্ত virus scanning ব্যবহার করা যেতে পারে।
Security Considerations
ফাইল আপলোডের নিরাপত্তা নিয়ে কাজ করার সময় কিছু প্রধান সুরক্ষা ব্যবস্থা গ্রহণ করা গুরুত্বপূর্ণ:
1. Path Traversal Attacks (Path manipulation)
ফাইল আপলোডের সময়, Path Traversal আক্রমণ রোধ করা অত্যন্ত গুরুত্বপূর্ণ। এটি তখন ঘটে যখন একজন অ্যাটাককারী ফাইলের নামের মধ্যে বিশেষ ক্যারেক্টার বা পাথ ট্রাভার্সাল কৌশল ব্যবহার করে সিস্টেমের নিরাপদ ডিরেক্টরি অ্যাক্সেস করার চেষ্টা করে। সুতরাং, ফাইলের পাথ সঠিকভাবে স্যানিটাইজ করা উচিত।
const path = require('path');
const filePath = path.join(__dirname, 'uploads', filename);
এখানে path.join() ব্যবহারের মাধ্যমে সঠিক ফাইল পাথ তৈরি করা হয়েছে, যা Path Traversal আক্রমণ প্রতিরোধে সাহায্য করে।
2. Limiting File Upload Types
কিছু ফাইল টাইপ (যেমন .exe, .bat, .js) নিরাপদ নয় এবং আপনার সিস্টেমে রান করার সম্ভাবনা থাকতে পারে। তাই আপলোডযোগ্য ফাইল টাইপ সীমিত করা উচিত।
const allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf'];
এছাড়াও, আপনি file extension যাচাই করতে পারেন, যেমন .jpg, .png, .pdf।
3. Limiting File Upload Size
ফাইল আপলোডের আকার সীমিত করা উচিত। বড় ফাইল সার্ভার এবং নেটওয়ার্কের উপর অতিরিক্ত চাপ সৃষ্টি করতে পারে, এবং এটি সিস্টেমের পারফরম্যান্স কমিয়ে দিতে পারে।
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 MB
if (file.size > MAX_FILE_SIZE) {
throw new Error('File size is too large');
}
4. Virus Scanning
আপনার সার্ভারে আপলোড হওয়া ফাইলগুলোকে virus scanning এর মাধ্যমে পরীক্ষা করা উচিত। এতে, ম্যালওয়্যার বা ক্ষতিকারক কোড ফাইলগুলোর মধ্যে উপস্থিত থাকলে তা সনাক্ত করা যাবে। আপনি ClamAV বা VirusTotal API ব্যবহার করতে পারেন।
5. Using Secure Storage for Files
আপনার সার্ভারে আপলোড করা ফাইলগুলো সঠিকভাবে সুরক্ষিত হওয়া উচিত। ফাইলগুলোর জন্য Secure Storage ব্যবস্থা নিতে হবে, এবং অনুমতি সঠিকভাবে সেট করতে হবে, যেন কোনো আক্রমণকারী ফাইলগুলোর অ্যাক্সেস করতে না পারে।
আপনার ফাইলগুলো ক্লাউড স্টোরেজ যেমন AWS S3 বা Google Cloud Storage তে সংরক্ষণ করা যেতে পারে, যেখানে ফাইল স্টোরেজের নিরাপত্তা ব্যবস্থাপনা সঠিকভাবে পরিচালিত হয়।
6. Restricting Access to Uploaded Files
ফাইল আপলোড করার পর, সেই ফাইলের অ্যাক্সেসের উপর নিয়ন্ত্রণ রাখতে হবে। কিছু ফাইল শুধুমাত্র অনুমোদিত ব্যবহারকারীদের জন্যই দৃশ্যমান হওয়া উচিত, যেমন প্রাইভেট ডকুমেন্টস বা ব্যাঙ্ক স্টেটমেন্টস।
AWS S3 ব্যবহার করার ক্ষেত্রে, signed URLs ব্যবহার করা যেতে পারে, যা নির্দিষ্ট সময়ের জন্য ফাইলের অ্যাক্সেস দেয়।
সারাংশ
GraphQL file upload এবং file validation হল এমন একটি প্রক্রিয়া, যেখানে আপনার ডেটা এবং সিস্টেমের নিরাপত্তা নিশ্চিত করতে কিছু সতর্কতা অবলম্বন করা প্রয়োজন। File size validation, file type validation, এবং virus scanning এর মাধ্যমে আপনি নিরাপদ ফাইল আপলোড সিস্টেম তৈরি করতে পারেন। এছাড়া, Path Traversal আক্রমণ, Limiting file types and sizes, এবং using secure storage এর মতো নিরাপত্তা পদ্ধতি আপনার সিস্টেমকে সুরক্ষিত রাখবে।
Read more