DEV Community

Imed Jaberi
Imed Jaberi

Posted on • Edited on

Serve Static File with GraphQL Yoga 🧘

I love the Prisma GraphQL Yoga ❤️ because it's from the future, and all the features you might see today from the Apollo Server are inspired by it. ( for more about yoga and apollo 👀)

So, I'd like to share how to solve a problem that encountered me when I tried to serve static files under graphql-yoga.

Before starting there are some terms that should be clarified for newcomers.

  • GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

  • GraphQL Yoga made by Prisma team, is fully-featured GraphQL Server with focus on easy setup, performance & great developer experience. It provides an abstraction on top of Apollo’s (apollo-server-express@1.x.x and other graphql tools).

Through GraphQL Yoga you have access to Express by server.express but you haven't access ❌ to the static method server.express.static().
Therefore, most developers have tended to adding Express as a dependency then use it like this.

// yarn add express or npm i express

// import express form 'express';
const express = require('express');

// server here is a GraphQL Yoga server
server.express.use('/uploads', express.static('uploadsDir')); // ✔️
Enter fullscreen mode Exit fullscreen mode

Personally, I think this method is somewhat confused. Why do I add Express as a dependency ? And I can solve this problem without that in few linges.

server.express.get('/uploads/*', (req, res, next) => {
  // here you can use your way to get the path dir ..  
  const pathDir = path.join(__dirname, `../uploads`);

  res.sendFile(pathDir);
}); // ✔️🚀
Enter fullscreen mode Exit fullscreen mode

If you want to turn a blind eye on the entrypoint, you can use '*' and add a small logic.

server.express.get('*', (req, res, next) => {
  // small logic .. 
  const routes = [
    '/graphql',
    '/subscriptions',
    '/playground'
  ];

  if(routes.includes(req.url)) {
    return next();
  }

  // here you can use your way to get the path dir ..  
  const pathDir = path.join(__dirname, `../uploads`);

  res.sendFile(pathDir);
});
Enter fullscreen mode Exit fullscreen mode

Top comments (0)