DAY05

yejichoi·2022년 11월 14일
0

CodeCamp

목록 보기
6/11
post-thumbnail

1. Algorithm Self Study

가장 큰 수 찾기
str은 무작위 숫자인 문자열입니다. 해당 문자열에서 가장 큰 수를 구하는 함수를 만들어야 합니다.
주의 사항

  • str에서 각각의 문자를 숫자로 바꿔서 계산해야 합니다.
  • 비교할 수 있는 기준값이 있어야 합니다.
  • 최댓값을 저장할 수 있는 변수가 있어야 합니다.
// 내 코드 
function bigNum(str) {
  let num = Number(str) // 숫자로 먼저 변환을 해주면 나중에 index로 접근을 못함...
	let biggest = 0;
  
  //기준값을 뭘로 잡지? 
  
  for(i = 0; i < str.length; i++) {
    if(num[i] > biggest){
      biggest = num[i];
    }
  }
 return biggest; 
}
  
bigNum("12345") // 5
bigNum("87135") // 8
// reference code
function bigNum(str) {

	let biggest = 0;
  
  for(i = 0; i < str.length; i++) {
    if(Number(str[i]) > biggest){ //biggest 가 0으로 선언되었기 때문 
      biggest = Number(str[i]);
    }
  }
 return biggest; 
}
  
bigNum("12345") // 5
bigNum("87135") // 8

조건문 실전 적용 - 점수에 따른 등급
100~90 → "A"
89~80 → "B"
79~70 → "C"
69~60 → "D"
59점 이하는 "F"
100점 초과나 0점 미만은 "잘못된 점수입니다"라는 문구를 띄워주세요.

function grade(score) {
  if(score > 100 || score < 0){ //조건을 수정해 줄 때 가장 마지막 조건부터 소거법 형태로 
    return "잘못된 점수입니다"
  }
  else if(score <= 59){
    return "F"
  } 
   else if(score <= 69){
    return "D"
  }
   else if(score <= 79){
    return "C"
  }
  
   else if(score <= 89){
    return "B"
  }
  
   else {
    return "A"
  }
  
}
  
grade(105)  // "잘못된 점수입니다"
grade(-10)  // "잘못된 점수입니다" => 해당 케이스때문에 오류
grade(97)   // "A"
grade(86)   // "B"
grade(75)   // "C"
grade(66)   // "D"
grade(52)   // "F"

마이페이지
해당 목록에서 "의류"를 구매한 횟수와 총 금액을 나타내고,
"의류"를 구매한 횟수에 따라 등급을 나타내세요.
등급표
"0~2" ⇒ Bronze
"3~4" ⇒ Silver
5이상 ⇒ Gold
예상결과
의류를 구매한 횟수는 총 5회 금액은 57000원이며 등급은 Gold입니다.

const myShopping = [
		{ category: "과일", price: 12000 },
		{ category: "의류", price:10000  },
		{ category: "의류", price: 20000 },
		{ category: "장난감", price: 9000 },
		{ category: "과일", price: 5000  },
		{ category: "의류", price: 10000  },
		{ category: "과일", price: 8000  },
		{ category: "의류", price: 7000  },
		{ category: "장난감", price: 5000  },
		{ category: "의류", price: 10000  },
]
//횟수 변수 선언
let count = 0
// 금액 변수 선언
let amount = 0
// 등급 변수 선언
let grade = ''
for(i = 0; i < myShopping.length; i++){

    if(myShopping[i].category === "의류"){ //배열안에 객체의 value 접근 
      count = count + 1;
      amount = amount + myShopping[i].price;
    
    } 
 }

if(count >= 5) {
  grade = "Gold"
}
else if(count >= 3){
  grade = "Silver"
}
else {
  grade = "Bronze"
}

let credit =`의류를 구매한 횟수는 총 ${count}회 금액은 ${amount}원이며 등급은 ${grade}입니다.` // 템플릿 리터럴 
console.log(credit)

2. Backend Class

CORS

Cross-Origin-Resource-Sharing
서로 다른 출처(origin)를 가진 주소로 요청이 들어왔을 때 발생할 수 있는 에러
i.e) url(http://localhost:3000/tokens/phone) => http://localhost:3000을 origin 이라 함
port번호가 다른 경우에도 CORS 에러는 발생하는데 이는 같은 localhost임에도 다른 출처로 인식되기 때문임

CORS 문제 해결

import cors from 'cors'; //import 
...
const app = express();
app.use(express.json());
app.use(cors()); // 추가된 부분
...
  • 보안과 관련해 특정 origin만을 허용해야한다면, app.use(cors({origin: })) 과 같이 작성하여 특정 origin만을 허용하도록 설정

GraphQL-API 만들기

// const { ApolloServer, gql } = require('apollo-server');
import { ApolloServer, gql } from 'apollo-server'

// The GraphQL schema
const typeDefs = gql`
  type Query {
    "A simple type for getting started!"
    hello: String
  }
`;

// A map of functions which return data for the schema.
const resolvers = { //express 서버를 사용할 때 보았던 api와 같은 역할
  Query: {
    hello: () => 'world',
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
}); //resolvers라는 객체 안에 있는 Query 객체에 작성해 놓은 hello 함수가 실행되면서 
//typeDefs 객체 안에 있는  type Query 객체에 지정해 놓은 데이터의 형태로 반환


server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

resolvers :express 서버를 사용할 때 보았던 api와 같은 역할

// express
app.get('/', function (req, res) {
  res.send('Hello Wordld')
})

// apollo-server
const resolvers = {
  Query: {
    hello: () => 'Hello world',
  },
};

typeDefs : express의 경우 swagger를 통해 api-docs를 직접 작성해주었는데 graphql의 경우 해당 부분을 typeDefs에서 swagger와 같이 api-docs를 자동으로 생성

fetchBoards API 생성

const resolvers = {
  Query: {
    fetchBoards: () => {
      // 1. 데이터를 조회하는 로직 => DB에 접속해서 데이터 꺼내오기
      const result = [
        {
          number: 1,
          writer: '철수',
          title: '제목입니다~~',
          contents: '내용이에요@@@',
        },
        {
          number: 2,
          writer: '영희',
          title: '영희 제목입니다~~',
          contents: '영희 내용이에요@@@',
        },
        {
          number: 3,
          writer: '훈이',
          title: '훈이 제목입니다~~',
          contents: '훈이 내용이에요@@@',
        },
      ];

      // 2. 꺼내온 결과 응답 주기
      return result;
    },
  },
}
  • Rest-API에서는 res.send를 이용해서 데이터를 반환했는데 graphql-API는 return을 사용해 함수를 종료하면서 데이터를 반환

createBoard API 생성

// 기본 세팅 
const resolvers = {
  Mutation: {
    createBoard: (parent, args, context, info) => {
     
    },
  },
};
  • parent : 부모 타입 resolver에서 반환된 결과를 가진 객체
  • args : 쿼리 요청 시 전달된 parameter를 가진 객체
  • context : GraphQL의 모든 resolver가 공유하는 객체로서 로그인 인증, 데이터베이스 접근 권한 등에 사용
  • info : 명령 실행 상태 정보를 가진 객체
const resolvers = {
  Query: {
    fetchBoards: () => {
      // ...
    },
  },

  Mutation: {
    createBoard: (_, args) => {
      // 1. 데이터를 등록하는 로직 => DB에 접속해서 데이터 저장하기
      console.log(args);

      // 2. 저장 결과 응답 주기
      return '게시물 등록에 성공하였습니다!!';
    },
  },
};
// Rest-API에서는 요청 데이터를 확인하기 위해 매개변수로 **req**를 사용

//GraphQL-AP에서는 4개의 매개변수 중 요청 데이터를 확인 가능한 **args**를 사용하여 
// 입력값을 가져옴
// 사용하지 않는 매개변수는 _(언더바)로 선언
const typeDefs = gql`
  input CreateBoardInput { //input을 사용해 데이터의 타입을 지정
    writer: String
    title: String
    contents: String
  }

  type Mutation {
    # createBoard(writer: String, title: String, contents: String):
# String => 입력값을 낱개로 받아오는 것을 의미
    createBoard(createBoardInput: CreateBoardInput!): String 
# => 입력값을 객체로 받아오는 것을 의미
  }
`;

3. HW

Rest-API를 GrapQL-API로 변경하기

// Rest-api 
import express from 'express'
import { checkValidationPhone, getToken, sendTokenToSMS } from './phone.js'
import swaggerUi from 'swagger-ui-express'
import swaggerJsdoc from 'swagger-jsdoc'
import { options } from './swagger/config.js'

const app = express()
app.use(express.json())
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerJsdoc(options)));
app.get('/boards', (req, res) => {
  
  const result = [
    { number: 1, writer: "철수", title: "제목입니다", contents: "내용입니다" },
    { number: 2, writer: "영희", title: "좋은 날씨입니다", contents: "내용입니다" },
  ]

  res.send(result)
})

app.post('/tokens/phone', (req, res) => {
  const myphone = req.body.myphone

  // 1. 휴대폰번호 자릿수 맞는지 확인하기
  const isValid = checkValidationPhone(myphone)
  if(isValid){
    // 2. 휴대폰 번호 자릿수가 맞다면 핸드폰 토큰 4자리 만들기
    const mytoken = getToken()

    // 3. 만든 토큰을 핸드폰번호에 토큰 전송하기
    sendTokenToSMS(myphone, mytoken)
    res.send("인증완료!!!")
  }
})

app.listen(3000, () => {
  console.log(`Example app listening on port ${3000}`)
})
///Graphql-api 

          number: 1,
          writer: "철수",
          title: "제목입니다",
          contents: "내용입니다",
        },
        {
          number: 2,
          writer: "영희",
          title: "좋은 날씨입니다",
          contents: "내용입니다",
        }
      ];
    },
  },
    

  Mutation: {
    createTokenOfPhone: (_, args) => {
      // 2. 아래 로직을 만들어 주세요.
      // (힌트: phone.js 내에 존재하는 함수들을 사용해서 로직을 완성해 주시면 됩니다.
      //  로직 구성이 어려우신 분들은 rest_api 폴더 내에 존재하는 index.js 파일을 참고해 주세요.)
      const myphone = args.phone;
      // 2-1. 휴대폰번호 자릿수 맞는지 확인하기
      const isValid = checkValidationPhone(myphone)
      if(isValid === false){
        return
      }
      
      // 2-2. 휴대폰 번호 자릿수가 맞다면 핸드폰 토큰 4자리 만들기
      const myToken = getToken()
      // 2-3. 만든 토큰을 핸드폰번호에 토큰 전송하기
      sendTokenToSMS(myphone,myToken)


      return "인증완료"      
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

server.listen(3000).then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

프론트엔드와 API 연동하기

import express from 'express'
import swaggerUi from 'swagger-ui-express'
import swaggerJsdoc from 'swagger-jsdoc'
import {options} from './swagger/config.js'
import cors from 'cors'


const app = express()
app.use(express.json())
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerJsdoc(options)));
app.use(cors())

app.get('/users',(req,res)=>{
    const result = [
        { 
            email : "aaa@gmail.com", 
            name : "철수",
            phone : "010-1234-5678",
            personal : "220110-1******",
            prefer : "https://naver.com"
        },
        { 
            email : "hoon2@gmail.com", 
            name : "훈이",
            phone : "010-7272-2727",
            personal : "221012-1******",
            prefer : "https://google.com"
        },
        { 
            email : "glass@gmail.com", 
            name : "유리",
            phone : "010-6262-2626",
            personal : "220509-2222222",
            prefer : "https://daum.com"
        },
        { 
            email : "mangGu@gmail.com", 
            name : "맹구",
            phone : "010-0909-9090",
            personal : "221227-1******",
            prefer : "https://yahoo.com"
        },
        { 
            email : "GGang@gmail.com", 
            name : "짱구",
            phone : "010-9090-0909",
            personal : "220505-1******",
            prefer : "https://youtube.com"
        }

    ]
    res.send(result)

})

app.get('/starbucks',(req,res)=>{
    const coffee = [
        { name: '아메리카노', kcal: 5 },
        { name: '카라멜 마키야또', kcal: 400 },
        { name: '바닐라 라떼', kcal: 450 },
        { name: '초코 라떼', kcal: 480 },
        { name: '그린티 라떼', kcal: 350 },
        { name: '고구마 라떼', kcal: 380 },
        { name: '콜드브루', kcal: 5 },
        { name: '에스프레소', kcal: 3 },
        { name: '초코 바나나스무디', kcal: 600 },
        { name: '바나나 딸기스무디', kcal: 550 }


    ]
    res.send(coffee)
    
})




app.listen(3000, () => {
    console.log(`백엔드 api 서버가 켜졌어요`)
  })

0개의 댓글