{"id":8512,"date":"2025-01-21T09:30:51","date_gmt":"2025-01-21T04:00:51","guid":{"rendered":"https:\/\/pheonixsolutions.com\/blog\/?p=8512"},"modified":"2025-01-21T09:37:54","modified_gmt":"2025-01-21T04:07:54","slug":"using-graphql-to-create-blogs-with-image-uploads-in-mongodb","status":"publish","type":"post","link":"https:\/\/pheonixsolutions.com\/blog\/using-graphql-to-create-blogs-with-image-uploads-in-mongodb\/","title":{"rendered":"Using GraphQL to Create Blogs with Image Uploads in MongoDB"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Using GraphQL to Create Blogs with Image Uploads in MongoDB<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To implement blog creation with image uploads, we\u2019ll use <strong>Apollo Server<\/strong> for GraphQL, <strong>MongoDB<\/strong> for data storage, and <strong>GridFS<\/strong> for handling binary file storage. Follow the steps below for seamless integration.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Prerequisites<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Install the required dependencies using Yarn:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>yarn add apollo-server graphql multer graphql-upload mongodb<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Enable file uploads in Apollo Server with the graphql-upload package.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Implementation<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>1. Setup Apollo Server with File Uploads<\/strong><\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>const<\/strong> resolvers = {<br>&nbsp; Upload: GraphQLUpload,<br>&nbsp; Mutation: {<br>&nbsp; &nbsp; createBlog: <strong>async<\/strong> (<br>&nbsp; &nbsp; &nbsp; _: any,<br>&nbsp; &nbsp; &nbsp; { title, content, image }: { title: string; content: string; image?: FileUpload }<br>&nbsp; &nbsp; ) =&gt; {<br>&nbsp; &nbsp; &nbsp; <strong>let<\/strong> imageId = null;<br><br>&nbsp; &nbsp; &nbsp; <strong>if<\/strong> (image) {<br>&nbsp; &nbsp; &nbsp; &nbsp; <strong>const<\/strong> { createReadStream, filename, mimetype } = <strong>await<\/strong> image;<br>&nbsp; &nbsp; &nbsp; &nbsp; <strong>const<\/strong> stream = createReadStream();<br><br>&nbsp; &nbsp; &nbsp; &nbsp; imageId = <strong>await<\/strong> <strong>new<\/strong> Promise((resolve, reject) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>const<\/strong> uploadStream = bucket.openUploadStream(filename, { contentType: mimetype });<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stream.pipe(uploadStream);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uploadStream.on(&#8220;finish&#8221;, () =&gt; resolve(uploadStream.id.toString()));<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uploadStream.on(&#8220;error&#8221;, reject);<br>&nbsp; &nbsp; &nbsp; &nbsp; });<br>&nbsp; &nbsp; &nbsp; }<br><br>&nbsp; &nbsp; &nbsp; <strong>const<\/strong> blog = {<br>&nbsp; &nbsp; &nbsp; &nbsp; title,<br>&nbsp; &nbsp; &nbsp; &nbsp; content,<br>&nbsp; &nbsp; &nbsp; &nbsp; imageId,<br>&nbsp; &nbsp; &nbsp; &nbsp; createdAt: <strong>new<\/strong> Date().toISOString(),<br>&nbsp; &nbsp; &nbsp; };<br><br>&nbsp; &nbsp; &nbsp; <em>\/\/ Assume `saveBlog` is a function to insert data into MongoDB or another database<\/em><br>&nbsp; &nbsp; &nbsp; <strong>const<\/strong> result = <strong>await<\/strong> saveBlog(blog);<br><br>&nbsp; &nbsp; &nbsp; <strong>return<\/strong> { id: result.id, &#8230;blog };<br>&nbsp; &nbsp; },<br>&nbsp; },<br>};<br><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Explanation<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>GraphQL Schema<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Upload Scalar<\/strong>: Handles file uploads using the graphql-upload package.<\/li>\n\n\n\n<li><strong>createBlog Mutation<\/strong>: Accepts title, content, and an optional image file.<\/li>\n\n\n\n<li><strong>blogs Query<\/strong>: Retrieves all blog posts with their metadata.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Resolvers<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>createBlog Mutation<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Processes the image file using createReadStream and stores it in MongoDB GridFS.<\/li>\n\n\n\n<li>Saves the blog metadata (title, content, and imageId) in the blogs collection.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>blogs Query<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Fetches all blogs from MongoDB and returns them, including the imageId.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>MongoDB GridFS<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Manages uploaded files in binary format.<\/li>\n\n\n\n<li>Generates a unique imageId for each file, stored alongside blog metadata.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Apollo Server<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Configured to support file uploads using graphql-upload.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Postman Operations<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Mutation Name:<\/strong><strong><br><\/strong> createBlog<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Description:<\/strong><strong><br><\/strong> The createBlog mutation allows you to create a blog post with the following parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>title (String, required): Title of the blog post.<\/li>\n\n\n\n<li>content (String, required): Content of the blog post.<\/li>\n\n\n\n<li>image (Upload, optional): An optional image file for the blog.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Mapping Example (Variables Section):<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>{<br>&nbsp; &#8220;map&#8221;: {<br>&nbsp; &nbsp; &#8220;&#8221;: [&#8220;variables.file&#8221;]<br>&nbsp; }<br>}<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>File Input (Index 0):<\/strong><strong><br><\/strong> Map the file being uploaded as &#8220;variables.file&#8221;, specifying its name in Postman\u2019s file upload section.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Retrieving Blogs<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Query:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>query GetBlogs {<br>&nbsp; blogs {<br>&nbsp; &nbsp; id<br>&nbsp; &nbsp; title<br>&nbsp; &nbsp; content<br>&nbsp; &nbsp; imageId<br>&nbsp; &nbsp; createdAt<br>&nbsp; }<br>}<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Description:<\/strong><strong><br><\/strong> This query retrieves all blog posts, including their metadata such as title, content, imageId, and createdAt.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using GraphQL to Create Blogs with Image Uploads in MongoDB To implement blog creation with image uploads, we\u2019ll use Apollo [&hellip;]<\/p>\n","protected":false},"author":507,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[1022],"tags":[],"class_list":["post-8512","post","type-post","status-publish","format-standard","hentry","category-web-architecture","psol-cat-web-architecture"],"jetpack_publicize_connections":[],"jetpack_shortlink":"https:\/\/wp.me\/phn2x7-2di","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8512","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/users\/507"}],"replies":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=8512"}],"version-history":[{"count":0,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8512\/revisions"}],"wp:attachment":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=8512"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=8512"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=8512"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}