묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결애플 웹사이트 인터랙션 클론!
50vh
.scroll-section { position: relative; padding-top: 50vh; } 위와 같이 padding-top에 50vh를 넣고 setLayout함수에서 if (sceneInfo[i].type === 'sticky') { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; } else if (sceneInfo[i].type === 'normal') { sceneInfo[i].scrollHeight = sceneInfo[i].objs.content.offsetHeight + window.innerHeight * 0.5; } sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`; sticky인 경우 innerHeight의 배수만큼만, normal인 경우 실제 높이에 50vh 만큼을 더해주고 있습니다. 질문1: 어짜피 setLayout에서 높이를 재설정하고 있는데 css에서 패딩을 주는 이유가 무엇일까요? 질문2: sticky와 normal에 50vh의 보정이 서로 다르게 들어가는 이유는 무엇일까요? 감사합니다~~
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
연관관계와 관계가 없다?
영속성 전이가 연관 관계 세팅과 전혀 관계가 없다는 설명이 잘 이해가 되지 않습니다. 연관 관계가 맺어져 있어야 영속성 전이도 이루어질텐데 어떤 의미에서 이렇게 설명하신건지 궁금합니다. 감사합니다.
-
미해결[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
강의 순서 관련 질문입니다. ^^
안녕하세요! 이전까지 MMDetection 실습 코드 설명이 끝난 뒤, SSD 개요 설명하사다가 갑자기 opencv_ssd_inference.ipynb을 설명하시는데, 설명하시는 걸 들어보니 tensorflow API를 이미 앞서 설명한 것처럼 말씀을 하셨습니다. 지금까지 강의에서 tensorflow는 처음 사용하셨는데 앞에 강의가 뭔가 빠진 느낌이네요 ^^ 21년 8월 이후 삭제한다고 되어 있는 강의 마지막 부분이 원래 이 영상 앞에 있었던 것인가요? 아울러, 권철민 강사님 깃헙에는 opencv_ssd_inference.ipynb 파일이 없습니다 ㅜㅜ 제가 무언가를 놓친 것인지 궁금합니다 :) 감사합니다!
-
해결됨남박사의 파이썬으로 실전 웹사이트 만들기
웹사이트 회원가입후 게시판으로 넘어가는 부분 질문 (join 부분)
안녕하세요 남박사님 도움을 많이 주셔서 강좌 잘 진행하고 있습니다! 몇일동안 헤매던것을 해결되서 정말 좋습니다! 궁금한 사항이 있어서 질문 올립니다. join창에서 회원가입을 하면 몽고db에 데이터가 정상적으로 넣어지는걸 확인할수있고 리스트란에서 게시물 작성 및 삭제등이 원활하게 이루어 지고 있습니다. 궁금한부분은 회원가입후 리스트나 로그인창으로 안넘어 가는거 같아서 질문을 올립니다! 회원로그인창으로 링크주소를 바꾸면 오류가 나는거 같더라구요.. 어떻게 해야할지 몰라서 질문 다시 올립니다! -회원가입- -회원 가입후- - 로그인 - -게시판 목록- -게시글 자성란- -게시글 작성후 - -회원가입 데이터- - run.py - from flask import Flask from flask import request from flask import render_template from flask_pymongo import PyMongo from bson.objectid import ObjectId from flask import abort from flask import redirect from flask import url_for from flask import flash from flask import session from functools import wraps import math import time from datetime import datetime, timedelta app = Flask(__name__) app.config["MONGO_URI"] = "mongodb://localhost:27017/myweb" app.config["SECRET_KEY"] = "abcd" app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(minutes=30) mongo = PyMongo(app) def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): if session.get("id") is None or session.get("id") == "": return redirect(url_for("member_login", next_url=request.url)) return f(*args, **kwargs) return decorated_function @app.template_filter('formatdatetime') def format_datetime(value): if value is None: return "" now_timestamp = time.time() offset = datetime.fromtimestamp( now_timestamp) - datetime.utcfromtimestamp(now_timestamp) value = datetime.fromtimestamp((int(value) / 1000)) + offset return value.strftime('%Y-%m-%d %H:%M:%S') @app.route("/list") def lists(): # 페이지 값 (값이 없는 경우 기본값는 1) page = request.args.get("page", 1, type=int) # 한페이지당 몇개의 게시물을 출력할지 limit = request.args.get("limit", 5, type=int) search = request.args.get("search", -1, type=int) keyword = request.args.get("keyword", "", type=str) # 최종적으로 완성된 쿼리를 만들 변수 query = {} # 검색어 상태를 추가할 리스트 변수 search_list = [] if search == 0: search_list.append({"title": {"$regex": keyword}}) elif search == 1: search_list.append({"contents": {"$regex": keyword}}) elif search == 2: search_list.append({"title": {"$regex": keyword}}) search_list.append({"contents": {"$regex": keyword}}) elif search == 3: search_list.append({"name": {"$regex": keyword}}) # 검색 대상이 한개라도 존재할 경우 query 변수에 $or 리스트를 쿼리 합니다. if len(search_list) > 0: query = {"$or": search_list} print(query) board = mongo.db.board datas = board.find({}).skip( (page - 1) * limit).limit(limit).sort("pubdate", -1) # 게시물의 총 갯수 tot_count = board.count_documents({}) # 마지막 페이지의 수를 구한다. last_page_num = math.ceil(tot_count / limit) # 페이지 블럭을 5개씩 표기 block_size = 5 # 현재 블럭의 위치 block_num = int((page - 1) / block_size) # 블럭의 시작 위치 block_start = int((block_size * block_num) + 1) # 블럭의 끝 위치 block_last = math.ceil(block_start + (block_size - 1)) return render_template("list.html", datas=list(datas), limit=limit, page=page, block_start=block_start, block_last=block_last, last_page_num=last_page_num, search=search, keyword=keyword) @ app.route("/view/<idx>") @login_required def board_view(idx): # idx = request.args.get("idx") if idx is not None: page = request.args.get("page") search = request.args.get("search") keyword = request.args.get("keyword") board = mongo.db.board # data = board.find_one({"_id": ObjectId(idx)}) data = board.find_one_and_update({"_id": ObjectId(idx)}, { "$inc": {"view": 1}}, return_document=True) if data is not None: result = { "id": data.get("_id"), "name": data.get("name"), "title": data.get("title"), "contents": data.get("contents"), "pubdate": data.get("pubdate"), "view": data.get("view"), "writer_id": data.get("writer_id", "") } return render_template("view.html", result=result, page=page, search=search, keyword=keyword) return abort(404) @ app.route("/write", methods=["GET", "POST"]) def board_write(): if session.get("id") is None: return redirect(url_for("member_login")) if request.method == "POST": name = request.form.get("name") title = request.form.get("title") contents = request.form.get("contents") print(name, title, contents) current_utc_time = round(datetime.utcnow().timestamp() * 1000) board = mongo.db.board post = { "name": name, "title": title, "contents": contents, "pubdate": current_utc_time, "writer_id": session.get("id"), "view": 0, } x = board.insert_one(post) print(x.inserted_id) return redirect(url_for("board_view", idx=x.inserted_id)) else: return render_template("write.html") @app.route("/join", methods=["GET", "POST"]) def member_join(): if request.method == "POST": name = request.form.get("name", type=str) email = request.form.get("email", type=str) pass1 = request.form.get("pass", type=str) pass2 = request.form.get("pass2", type=str) if name == "" or email == "" or pass1 == "" or pass2 == "": flash("입력되지 않은 값이 있습니다.") return render_template("join.html") if pass1 != pass2: flash("비밀번호가 일치하지 않습니다.") return render_template("join.html") members = mongo.db.members cnt = members.count_documents({"email": email}) if cnt > 0: flash("중복된 이메일 주소입니다.") return render_template("join.html") current_utc_time = round(datetime.utcnow().timestamp() * 1000) post = { "name": name, "email": email, "pass": pass1, "joindate": current_utc_time, "logintime": "", "logincount": 0, } members.insert_one(post) return "" else: return render_template("join.html") @app.route("/login", methods=["GET", "POST"]) def member_login(): if request.method == "POST": email = request.form.get("email") password = request.form.get("pass") next_url = request.form.get("next_url") members = mongo.db.members data = members.find_one({"email": email}) if data is None: flash("회원 정보가 없습니다.") return redirect(url_for("member_login")) else: if data.get("pass") == password: session["email"] = email session["name"] = data.get("name") session["id"] = str(data.get("_id")) session.permanent = True if next_url is not None: return redirect(next_url) else: return redirect(url_for("lists")) return redirect(url_for("lists")) else: flash("비밀번호가 일치하지 않습니다.") return redirect(url_for("member_login")) return "" else: next_url = request.args.get("next_url", type=str) if next_url is not None: return render_template("login.html", next_url=next_url) else: return render_template("login.html") @app.route("/edit/<idx>", methods=["GET", "POST"]) def board_edit(idx): if request.method == "GET": board = mongo.db.board data = board.find_one({"_id": ObjectId(idx)}) if data in None: flash("해당 게시물이 존재하지 않습니다.") return redirect(url_for("lists")) else: if session.get("id") == data.get("writer_id"): return render_template("edit.html", data=data) else: flash("글 수정 권한이 없습니다.") return redirect(url_for("lists")) else: title = request.form.get("title") contains = request.form.get("contents") board = mongo.db.board data = board.find_one({"_id": ObjectId(idx)}) if session.get("id") == data.get("writer_id"): board.update_one({"_id": ObjectId(idx)}, { "$set": { "title": title, "contents": contains, } }) flash("수정 되었습니다.") return redirect(url_for("board_view", idx=idx)) else: flash("글 수정 권한이 없습니다.") return redirect(url_for("lists")) @app.route("/delete/<idx>") def board_delete(idx): board = mongo.db.board data = board.find_one({"_id": ObjectId(idx)}) if data.get("writer_id") == session.get("id"): board.delete_one({"_id": ObjectId(idx)}) flash("삭제 되었습니다.") else: flash("삭제 권한이 없습니다.") return redirect(url_for("lists")) if __name__ == "__main__": app.run(host="0.0.0.0", debug=True, port=9000) --------------------------------------------------------------------------------- -join- {% with messages = get_flashed_messages() %} {% if messages %} <script> alert("{{messages[-1]}}"); </script> {% endif %} {% endwith %} <table> <form name="form" action="/join" method="POST"> <thead> <caption> 회원가입 </caption> </thead> <tbody> <tr> <td>이름</td> <td><input type="text" name="name" /></td> </tr> <tr> <td>이메일</td> <td><input type="text" name="email" /></td> </tr> <tr> <td>비밀번호</td> <td><input type="password" name="pass" /></td> </tr> <tr> <td>비밀번호 확인</td> <td><input type="password" name="pass2" /></td> </tr> <tr> <td colspan="2"><input type="submit" value="가입하기" /></td> </tr> </tbody> </form> </table> --------------------------------------------------------------------------------------- -login- {% with messages = get_flashed_messages() %} {% if messages %} <script> alert("{{messages[-1]}}"); </script> {% endif %} {% endwith %} <table> <form name="form" action="/login" method="POST"> {% if next_url %} <input type="hidden" name="next_url" value="{{next_url}}" /> {% endif %} <thead> <caption> 회원 로그인 </caption> </thead> <tbody> <tr> <td>이메일</td> <td><input type="text" name="email" /></td> </tr> <tr> <td>비밀번호</td> <td><input type="password" name="pass" /></td> </tr> <tr> <td colspan="2"><input type="submit" value="로그인" /></td> </tr> </tbody> </form> </table> ------------------------------------------------------------------------------------ -list- {% with messages = get_flashed_messages() %} {% if messages %} <script> alert('{{messages[-1]}}'); </script> {% endif %} {% endwith %} <script> function search() { var v_search = document.getElementById("search").value; var v_keyword = document.getElementById("keyword").value; if (v_search == "" || v_keyword == "") { return false; } else { self.location.href = "{{url_for('lists')}}?search=" + v_search + "&keyword=" + v_keyword; } } </script> {% if datas|length > 0 %} <table> <thead> <tr> <td>번호</td> <td>제목</td> <td>이름</td> <td>날짜</td> <td>조회수</td> </tr> </thead> <tbody> <!--반복되는 구간--> <tr> {% for data in datas %} <td>{{loop.index + ((page - 1) * limit)}}</td> <td> <a href="{{url_for('board_view', idx=data._id, page=page, search=search, keyword=keyword)}}">{{data.title}}</a> </td> <td>{{data.name}}</td> <td>{{data.pubdate|formatdatetime}}</td> <td>{{data.view}}</td> </tr> {% endfor %} <!--반복되는 구간 끝--> </tbody> </table> {% if block_start - 1 > 0 %} <a href="{{url_for('lists', page=block_start - 1, search=search, keyword=keyword)}}">[이전]</a> {% endif %} {% for i in range(block_start, block_last + 1) %} {% if i > last_page_num %} {{ i }} {% else %} {% if i == page %} <b>{{ i }}</b> {% else %} <a href="{{url_for('lists', page=i, search=search, keyword=keyword)}}">{{ i }}</a> {% endif %} {% endif %} {% endfor %} {% if block_last < last_page_num %} <a href="{{url_for('lists', page=block_last + 1, search=search, keyword=keyword)}}">[다음]</a> {% endif %} <select name="search" id="search"> <option value="" {% if search=='' or search==-1 %} selected {% endif %}>검색대상</option> <option value="0" {% if search==0 %} selected {% endif %}>제목</option> <option value="1" {% if search==1 %} selected {% endif %}>내용</option> <option value="2" {% if search==2 %} selected {% endif %}>제목+내용</option> <option value="3" {% if search==3 %} selected {% endif %}>작성자</option> </select> <input type="text" name="keyword" id="keyword" {% if keyword !="" %} value="{{keyword}}" {% endif %} /> <input type="button" value="검색" onclick="search()" /> {% else %} <h3>데이터가 없습니다.</h3> {% endif %} <a href="{{url_for('board_write')}}">글작성</a> ---------------------------------------------------------------------------------------- -view- <html> {% with messages = get_flashed_messages() %} {% if messages %} <script> alert("{{messages[-1]}}"); </script> {% endif %} {% endwith %} {{result.title}} <br /> {{result.name}} <br /> {{result.pubdate|formatdatetime}} <br /> {{result.view}} <br /> {{result.contents}} <br /> <a href="{{url_for('lists', page=page, search=search, keyword=keyword)}}" >리스트</a > {% if session["id"] == result.writer_id %} <a href="{{url_for('board_delete', idx=result.id)}}">글삭제</a> <a href="{{url_for('board_edit', idx=result.id)}}">글수정</a> {% endif %} </html> ---------------------------------------------------------------------------------------------------- -write- <html> <body> <table> <form name="form" method="post" action="/write"> <tr> <td>작성자</td> <td><input type="text" name="name" value="{{session['name']}}" readonly /></td> </tr> <tr> <td>제목</td> <td><input type="text" name="title" /></td> </tr> <tr> <td>내용</td> <td><textarea type="text" name="contents"></textarea></td> </tr> <tr> <td colspan="2"><input type="submit" /></td> </tr> </form> </table> </body> </html> ------------------------------------------------------------------------------------------------------ -edit- <html> <body> <table> <form name="form" method="post" action="/edit/{{data._id}}"> <tr> <td>작성자</td> <td><input type="text" name="name" value="{{session['name']}}" readonly /></td> </tr> <tr> <td>제목</td> <td><input type="text" name="title" /></td> </tr> <tr> <td>내용</td> <td><textarea type="text" name="contents">{{data.contents}}</textarea></td> </tr> <tr> <td colspan="2"><input type="submit" /></td> </tr> </form> </table> </body> </html> -
-
미해결사물인터넷 통신은 내 손에 (Arduino, MQTT, Nodejs, MongoDB, Android,VS Code)
DHT11 센서에서 NaN 값이 나옵니다
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 강사님, 강의 잘 보고 있습니다. 다름이 아니라 DHT11을 이용하여 온도와 습도를 받아오려고 하는데 시리얼 모니터에서 계속 nan 값이 불러와집니다. 보드연결은 다 잘 된것 같은데 무슨 이유 때문인지 잘 모르겠습니다...
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
API 메서드 안에서 엔티티 조회
회원 수정을 할 때 수정하고 id를 통해서 Member 엔티티를 반환하는데 이런 경우에도 엔티티 대신 DTO를 만들어서 반환하는 게 좋을까요?? Member findMember = memberService.findById(memberId);MemberDTO findMember = memberService.findById(memberId); 결국엔 UpdateMemberResponse에 데이터를 담아서 반환하니까 엔티티를 받아서 사용해도 되는걸까요??
-
미해결공공데이터로 파이썬 데이터 분석 시작하기
pandas-profiling module error
conda install, pip install 모두 설치된거 확인했는데 import 하면 아래와 같이 모듈에러가 납니다.... .
-
미해결자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
알려주신 peek메서드를 사용해서 풀 수는 없나요?
import java.util.*; // ()(((()())(())()))(()) -> 17 // (((()(()()))(())()))(()()) -> 24 class Main { public Integer solution(String str) { int answer = 0; Stack<Character> stack = new Stack<>(); for(char x : str.toCharArray()) { if(x=='(') { stack.push(x); } else { if(stack.peek()=='(') { stack.pop(); answer+=stack.size(); } else { stack.pop(); answer++; } } } return answer; } public static void main(String[] args) { Main T = new Main(); Scanner kb = new Scanner(System.in); String str = kb.next(); System.out.println(T.solution(str)); } } 이런식으로 짜봤는데 첫번째 입력은 올바르게 출력되는데 두번째 입력은 잘못출력됩니다. 아무리 생각해도 뭐가 잘못됐는디 모르겠습니다. 어느 부분이 잘못 된건가요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
트랜잭션과 영속성 컨텍스트
안녕하세요, 이번 수업에서 트랜잭션과 영속성 컨텍스트 두 개념을 섞어서 사용하셨는데, 두 가지가 같은 개념이라고 봐도 괜찮을까요? 예를 들어 JPA에서는 같은 트랜잭션 내에서 PK가 같으면 같은 객체로 인식한다고 하셨는데, '같은 영속성 컨텍스트'로 대체해도 같은 말이라고 이해하면 될까요?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
Boiler Plate 기본 코드의 대한 설명은 따로 없는건가요??
제목 그대로 입니다. 예를 들면 models의 user.js는 왜 이렇게했고 하는 설명은 따로 없는건가요?? 만약 다른 강의에 있다면 그 강의는 무엇인지 알수있나요?
-
미해결함수형 프로그래밍과 JavaScript ES6+ 응용편
함수의 구분자는 어떤것이 있을까요?
함수의 구분자라고 했을 때 어떤 것을 말하는지 감이 조금 안잡혀서요. 구체적으로 어떤 것인지 알려주시면 감사하겠습니다!
-
미해결면접과 취업을 부르는 '퍼블리셔 개인 포트폴리오 홈페이지' 제작
주석처리 위치
주석처리 시 </header><!--header end--> 이렇게 태그가 끝나는 부분에 엔터없이 사용해왔는데, <!--header--> <header> 이런식으로 태그 시작할 때 넣는게 바람직할까요?
-
미해결[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
pretrained된 모델을 사용하는 이유와 사용하지 않고 학습시키는 방법에 대해서 질문이 있습니다.
수업을 계속 듣는중에 생각난 것인데요 mmdetection에서 pretrained된 모델을 config에서 설정하여 train시킬때 pretrained된 모델을 왜 넣어야하는지가 궁금하고, 꼭 넣어야 되는지도 궁금합니다. 코로나에 걸리셨다고 공지를 통해 봤는데 쾨차하시길 바랍니다!!
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
실무에서도 repository를 도메인마다 따로 만드나요??
이 강의는 도메인 별로 각 각 repository랑 service를 만들었는데 예제에서만 그런건지 실제로 실무에서도 그런지 궁금합니다 ㅠㅠ
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
안녕하세요
안녕하세요 강의 다 마무리하고 추가 기능 추가하면서 해결안되는게 있어 질문드립니다. 모달로그인 기능을 추가하였습니다. (로그인 두곳에서 가능 =>일반, 모달)여기서 로그인실패 message 상태값을 사용하는 component들이 다 호출되는데 이걸 어떻게 해결 해야될지 잘모르겠습니다. (설명하기가 좀 어렵네요) 모달or 일반 로그인 실패 msg => const { loginErr} = useSelector((state) => state.user) loginErr 사용되는 곳은 모달로그인 컴퍼넌트와 일반 로그인 컴퍼넌트 ... 로그인 실패시 const { loginErr, } = useSelector((state) => state.user) useEffect(() => { if (!mounted.current) { mounted.current = true } else { if (loginErr) { console.log(loginErr) alert(loginErr) // } } }, [loginErr]) 위 코드가 모달로그인과 일반 로그인 똑같이 되어있는데 둘 중하나로 로그인하여 실패시 alert 창이 두번 실행됩니다. 이걸 해결할수 있는 방법 없을까요? 버튼 클릭시 모달내부 코드들이 실행될줄 알고 했는데 생각 처럼 잘 안죕니다. 왜 그런지는 알겠는데 해결방법을 잘 모르겠습니다. 사이트는 tweeter.ga 입니다. 항상 감사합니다.
-
미해결면접과 취업을 부르는 '퍼블리셔 개인 포트폴리오 홈페이지' 제작
브라켓 지원 종료
안녕하세요. 국비학원 다니면서 브라켓을 위주로 써왔는데요. 작년에 브라켓이 지원 종료되었다고 하는데, 요즘에도 계속 사용해도 되는 건가요?
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
중간에 영상 편집이 잘못 된거 같습니다.
중간에 내용이 짤리는것 같습니다.
-
미해결프로그래밍 시작하기 : 파이썬 입문 (Inflearn Original)
강의자료
챔터 09-01의 강의자료는 어디서 다운 받을 수 잇나요? py파일만 보이고 다른 파일들은 도저히 보이지가 않아서요
-
미해결부트스트랩 5(Bootstrap 5) - 기초부터 웹 프로젝트 만들기
trandsform translateY
trandsform translateY transition ease 어떤 기능인가요?
-
미해결React 기반 Gatsby로 기술 블로그 개발하기
develop 은 되는데 build 환경에서의 오류
Building static HTML failed for path "/main/postItem/" See our docs page for more info on this error: https://gatsby.dev/debug-html 19 | categories, 20 | summary, > 21 | thumbnail: { publicURL }, | ^ 22 | link, 23 | }) => { 24 | return ( WebpackError: TypeError: Cannot read properties of undefined (reading 'publicURL') - postItem.tsx:21 gatsby-starter-default/src/pages/main/postItem.tsx:21:16 - inheritsLoose.js:5 [gatsby-starter-default]/[@babel]/runtime/helpers/inheritsLoose.js:5:1 - emotion-is-prop-valid.esm.js:15 [gatsby-starter-default]/[@emotion]/is-prop-valid/dist/emotion-is-prop-valid.esm.js:15:1 - inheritsLoose.js:7 [gatsby-starter-default]/[@babel]/runtime/helpers/inheritsLoose.js:7:1 - static-entry.js:294 gatsby-starter-default/.cache/static-entry.js:294:22 - history.js:49 [gatsby-starter-default]/[@gatsbyjs]/reach-router/es/lib/history.js:49:6 publicUrl 이 없으면 build 환경에서 잘 동작합니다. 저 구문만 있으면 build 환경에서 돌아가지 않습니다..! https://github.com/urther/example 레포 주소 첨부합니다 ㅠㅠ 8000/graphql 에서 publicUrl 정상 동작하는것도 확인했습니다!