-
24.05.31 Supabase [ SpartaHub 팀프로젝트 1 ]sparta TIL 2024. 5. 26. 18:37
BaaS(Backend As A System)?
웹과 모바일 앱 개발을 쉽고 빠르게 할 수 있도록 도와주는 클라우드 기반의 백엔드 서비스이며
복잡한 백엔드 시스템을 직접 관리하지 않아도 되니 프론트엔드 개발에 더 집중할 수 있다.
[ ▼ 인기 있는 BaaS 플랫폼 ]
Firebase: Google이 운영하는 플랫폼으로 실시간 데이터베이스, 사용자 인증, 애널리틱스 등을 쉽게 이용할 수 있다.
Parse: 자유도가 높은 오픈 소스 BaaS로 커스터마이징이 가능해 많은 개발자에게 사랑받고 있다.
AWS Amplify: 강력한 AWS 클라우드 기반으로 복잡한 백엔드 작업을 손쉽게 할 수 있게 도와준다.
[ BaaS 사용시 장/단점 ]
개발 속도 향상: 백엔드를 직접 만들 필요가 없어서 이미 준비된 기능들을 바로 사용할 수 있으니, 개발 시간을 크게 단축할 수 있다
유지보수 간편: 서버 운영이나 백엔드 시스템 관리에 대한 걱정이 줄어들어 유지보수가 훨씬 편해진다.
자동 확장: 사용자가 늘어나도 서비스가 자동으로 스케일 업 되어 서버 부하 걱정 없이 안정적인 서비스를 제공할 수 있다.
유연성 부족: 표준화된 기능 외의 특별한 요구사항을 충족시키기 어려울 수 있다.
비용 예측 어려움: 사용량이 많아질수록 비용도 늘어난다. 때로는 초기에 예상했던 비용보다 많이 들 수도 있다.
플랫폼 의존성: 한 플랫폼에 의존하게 되면 나중에 다른 서비스로 이전하기 어렵다.
우리는 Supabase 써볼 것 !
Supabase는 PostgreSQL을 기반으로 하는 오픈 소스 BaaS 플랫폼.
Firebase의 대안으로 자리잡으면서, 관계형 데이터베이스를 사용하면서도 실시간 기능을 원하는 개발자들 사이에서 인기를 끌고 있다.
( 관계형 데이터베이스를 사용하면 복잡한 데이터 관계도 쉽게 표현할 수 있고, 강력한 쿼리 기능을 활용할 수 있다 )
Supabase?
Supabase는 단순한 BaaS가 아니다.
PostgreSQL을 사용하여 관계형 데이터를 관리하면서도, 실시간으로 데이터 변화를 감지하고 반응할 수 있는 기능을 제공한다.
즉, 데이터베이스 업데이트가 필요할 때마다 사용자 인터페이스가 자동으로 반응하여 변경사항을 보여준다는 것
// 설치 yarn add @supabase/supabase-js # 또는 npm install @supabase/supabase-js
[ Fetch 하기 ]
▼ supabase 사이트에서 프로젝트 생성
스크롤 내리면 url이랑 key있음 row추가 뿅 데이터 불러와진 것 확인 // App.jsx import FetchData from "./components/FetchData"; const App = () => { return ( <> <h1>supabase</h1> <FetchData /> </> ); }; export default App;
// supabaseClient.js import { createClient } from "@supabase/supabase-js"; // project url const SUPABASE_PROJECT_URL = "플젝url"; // anon key const SUSPA_BASE_ANON_KEY = "키"; const supabase = createClient(SUPABASE_PROJECT_URL, SUSPA_BASE_ANON_KEY); export default supabase;
// FetchData.jsx import { useEffect } from "react"; import supabase from "../supabaseClient"; import { useState } from "react"; const FetchData = () => { const [users, setUsers] = useState([]); useEffect(() => { const fetchData = async () => { const { data, error } = await supabase.from("NACAMP_SAMPLE").select("*"); if (error) { console.log(error); } else { console.log(data); setUsers(data); } }; fetchData(); }, []); return ( <div> <h3>유저정보</h3> {users.map((user) => { return ( <div key={user.id}> <h5>이름 : {user.name}</h5> <h5>나이 : {user.age}</h5> <h5>주소 : {user.address}</h5> </div> ); })} </div> ); }; export default FetchData;
추가한 데이터까지 잘 불러와 진다.
[ 추가, 수정, 삭제 ]
1. 추가
// App.jsx import AddData from "./components/AddData"; import FetchData from "./components/FetchData"; const App = () => { return ( <> <h1>supabase</h1> <FetchData /> <AddData /> </> ); }; export default App;
// FetchData.jsx import { useEffect } from "react"; import supabase from "../supabaseClient"; import { useState } from "react"; const FetchData = () => { const [users, setUsers] = useState([]); useEffect(() => { const fetchData = async () => { const { data, error } = await supabase.from("NACAMP_SAMPLE").select("*"); if (error) { console.log(error); } else { console.log(data); setUsers(data); } }; fetchData(); }, []); return ( <div> <h3>유저정보</h3> {users.map((user) => { return ( <div key={user.id}> <h5>이름 : {user.name}</h5> <h5>나이 : {user.age}</h5> <h5>주소 : {user.address}</h5> </div> ); })} </div> ); }; export default FetchData;
// AddData.jsx import { useState } from "react"; import supabase from "../supabaseClient"; const AddData = () => { const [name, setName] = useState(""); const [age, setAge] = useState(0); const [address, setAddress] = useState(""); const handleAdd = async () => { const { data, error } = await supabase.from("NACAMP_SAMPLE").insert({ name, age, address, }); if (error) { console.log(error); } else { console.log("성공", data); } }; return ( <div style={{ border: "1px solid red" }}> <h2>데이터 추가 로직</h2> <div> 이름 : <input type="text" value={name} onChange={(e) => { setName(e.target.value); }} /> </div> <div> 나이 : <input type="text" value={age} onChange={(e) => { setAge(e.target.value); }} /> </div> <div> 주소 : <input type="text" value={address} onChange={(e) => { setAddress(e.target.value); }} /> </div> <button onClick={handleAdd}>등록</button> </div> ); }; export default AddData;
2. 수정
// App.jsx import AddData from "./components/AddData"; import FetchData from "./components/FetchData"; import UpdateData from "./components/UpdateData"; const App = () => { return ( <> <h1>supabase</h1> <FetchData /> <UpdateData /> <AddData /> </> ); }; export default App;
// FetchData.jsx <h6>ID : {user.id}</h6> // id부분만 추가
// UpdateData.jsx import { useState } from "react"; import supabase from "../supabaseClient"; const UpdateData = () => { const [targetId, setTargetId] = useState(0); const [address, setAddress] = useState(""); const handleEdit = async () => { const { error } = await supabase .from("NACAMP_SAMPLE") .update({ address, }) .eq("id", targetId); if (error) { console.log(error); } }; return ( <div style={{ border: "1px solid yellow", }} > <h2>데이터 수정 로직</h2> 아이디 : {""} <input type="number" value={targetId} onChange={(e) => { setTargetId(e.target.value); }} /> <br /> 수정주소 : {""} <input type="text" value={address} onChange={(e) => { setAddress(e.target.value); }} /> <div> <button onClick={handleEdit}>수정</button> </div> </div> ); }; export default UpdateData;
3. 삭제
// App.jsx <DeleteData /> // 추가된 코드
// DeleteData.jsx import { useState } from "react"; import supabase from "../supabaseClient"; const DeleteData = () => { const [targetId, setTargetId] = useState(0); const handleDelete = async () => { const { error } = await supabase .from("NACAMP_SAMPLE") .delete() .eq("id", targetId); if (error) { console.log(error); } }; return ( <div style={{ border: "1px solid white", }} > <h2>데이터 삭제 로직</h2> 아이디 : {""} <input type="number" value={targetId} onChange={(e) => { setTargetId(e.target.value); }} /> <br /> <div> <button onClick={handleDelete}>삭제</button> </div> </div> ); }; export default DeleteData;
알고리즘 타임어택
// 문자열 myString이 주어집니다. "x"를 기준으로 해당 문자열을 잘라내 // 배열을 만든 후 사전순의 역으로 정렬한 배열을 return 하는 solution 함수를 완성해 주세요. // 단, 빈 문자열은 반환할 배열에 넣지 않습니다. // 입출력 예 // "axbxcxdx" => ["d","c","b","a"] // "dxccxbbbxaaaa" => ["d","cc","bbb","aaaa"] function solution(my_String) { return my_String .split("x") .filter((a) => a !== "") .reverse(); } // 테스트 코드 function runTests() { const testCases = [ { input: "abcxdefxghi", expected: ["ghi", "def", "abc"] }, { input: "helloxworld", expected: ["world", "hello"] }, { input: "xhelloxworldx", expected: ["world", "hello"] }, { input: "x", expected: [] }, { input: "abc", expected: ["abc"] }, ]; testCases.forEach((testCase, index) => { const result = solution(testCase.input); const isEqual = JSON.stringify(result) === JSON.stringify(testCase.expected); console.log(`Test Case ${index + 1} : ${isEqual ? "Passed" : "Failed"}`); console.log( `Input: "${testCase.input}", Expected: ${JSON.stringify( testCase.expected )}, Result: ${JSON.stringify(result)}` ); console.log("----------------------------------------------"); }); } // 테스트 실행 runTests();
reverse() - 리스트의 순서를 뒤집는다
[ 자바스크립트 베이직 ]
수업이 3시에 시작해서 4시~5시 끝인데, S.A(Starting Assignments) 팀노션 제출 마감 시간이 4시..! 발제 끝나고 2~3시간 만에
기획, 와이어프레임, 팀노션 작성 끝내라는 것ㅎㅎ 스파르타 이름 너무 잘 지었다 👍🏻
figma 잘 알지 못 하지만 팀원 분들과 우당탕탕 하다가 결국 자바스크립트 강의 들으면서도 했다. 강의 제대로 못들었다. ..
따로 공부해야 될 것들이 쌓여만 간다. 하루 종일 정말 계-속 뭔가를 하는데 더 많아지는 마법. 코딩을 잘 했었더라면 수월했겠지 🥹
[ SpartaHub 팀프로젝트 1 ]
실질적으로 주어진 기간이 주말 빼고 발제날인 오늘 까지 포함 해서 4일.
그 안에 팀노션, 기획, 디자인, 개발, 결과보고서PPT, 시연영상따로, 발표준비 까지 해야 한다.
마음이 너무 급해서 회의도 많이 하고 당장 할 수 있는것들 하나씩 하다보니 오늘 기획, 분담, 노션, 와이어프레임, 협업 브랜치도 생성 !
우리 팀 모두에게 박수 👏
와이어프레임 팀노션
https://www.notion.so/teamsparta/B09-0bb6536707e0447f8ae3b915bf33d7cf
깃헙 - 오늘은 reset.css/.prettierrc/designToken.css 만 PR 했다.
.prettierrc - 발제 내용 중 '코드포맷팅 규칙을 동일하게 설정하기 위해'라는 협업 활용 제안으로 추가
designToken.css - 지난 movie플젝때 팀원분이 하셨던 걸 표본삼아서 해봤다. 기본컬러는 그대로 두고, 현 플젝에 쓰일 컬러들 추가
'sparta TIL' 카테고리의 다른 글
24.06.03 TIL (0) 2024.06.03 24.06.01 TIL (0) 2024.06.02 24.05.30 TIL Router DOM1,2,3 (0) 2024.05.26 24.05.29 Redux 4,5,6 (0) 2024.05.26 24.05.28 Redux 1,2,3 (0) 2024.05.25