hQl 프로젝트 - -4

File upload

사진을 업로드 하기 위해서 Upload 타입을 정의해주어야 한다.
하지만 apollo-server를 이용해 schema를 만들면 자동적으로 Upload 타입을 정의해준다.

File upload를 하려면 playground 말고 다른 클라이언트를 사용해야한다.(테스트 용도로)

https://altair.sirmuel.design/

playground나 altair에 scalar upload가 없으면

$ npm install [email protected]
아폴로 서버를 다운 그레이드 해야한다.

유저 서버에게 업로드를 함-> 서버는 aws에 업로드를 함 -> aws는 서버에게 url 을 줌

node 12 이상 버전에서 에러가 생김

해결법

// in pacage.json

"resolutions": {
        "fs-capacitor": "^6.2.0",
        "graphql-upload": "^11.0.0"
    },


"scripts": {
        "preinstall": "npx [email protected]",

node_module 삭제

npm i

Node js 파일 다루기

import {createWriteStream} from "fs";


// altire 에서 받은 파일에는 stream과 파일명이 있다.
const {filename, createReadStream} = await avatarURL;

// 받은 스트림으로 객체를 하나 만들어주고
   const readStream = createReadStream();
   
   // nodejs 에서 제공하는 write stream으로 객체를 만든다.
   // 매개변수로 path 를 지정해준다.
   const writeStream = createWriteStream(
       process.cwd() + "/uploads/" + filename
   );
   
// 파일을 읽고 파이프를 이용해 설정한 path로 파일을 이동시켜준다.   
readStream.pipe(writeStream);

하지만 http://localhost:4000/uploads/filename 에 가도 아무것도 받지 못한다
아폴로 서버가 파일의 존재를 알지 못해서

아폴로 서버만을 사용해서는 url을 변경할 수 없다. (graphql 서버이기때문)
해결하기 위해서는 아폴로 서버를 express 서버로 감싸주는것이 한 방법이다.

apollo-server -> apollo-server-express

express 서버를 사용하되 graphql url 에서는 아폴로 서버를 사용하게 한다.

// in server.js

require("dotenv").config();
import express from "express";
import {ApolloServer, gql} from "apollo-server-express";
import morgan from "morgan";

import {resolvers, typeDefs} from "./schema";
import {getUser} from "./User/user.utils";

const PORT = process.env.PORT;

const apolloServerr = new ApolloServer({
   resolvers,
   typeDefs,
   context: async ({req}) => {
       return {
           loggedInUser: await getUser(req.headers.token),
       };
   },
});

const expressServer = express();
expressServer.use(morgan("dev"));
apolloServerr.applyMiddleware({app: expressServer});

expressServer.listen({port: PORT}, () =>
   console.log("Server is reunning http://localhost:4000")
);

express 에서 사용하던 것을 다 쓸 수 있다.

위 오류가 나면

$npm i [email protected] 다운그레이드 시켜준다.

expressServer.use("/static", express.static("uploads"));

prisma에 avatarUrl 저장

  let avatar = null;
    if (avatarURL) {
        const {filename, createReadStream} = await avatarURL;
        const newFilename = `${loggedInUser.id}-${Date.now()}-${filename}`;
        const readStream = createReadStream();
        const writeStream = createWriteStream(
            process.cwd() + "/uploads/" + newFilename
        );
        console.log(newFilename);
        readStream.pipe(writeStream);
        avatar = `http://localhost:4000/static/${newFilename}`;
    }

좋은 웹페이지 즐겨찾기