redwoodJS 및faunaDB를 사용하여 최소 스택 구축

소개


레드우드 JS


RedwoodJS는 자신의 의견을 고집하고 전 창고, 서버가 없는 웹 응용 프로그램 프레임워크로 Jamstack 응용 프로그램을 구축하고 배치하는 데 사용된다.톰 프레스턴 워너(Tom Preston Werner)가 창립하여 지난 5-10년 동안 이 업계에 영향을 미친 각종 기술과 기술을 결합시켰다.여기에는 다음이 포함됩니다.
  • 반응 전단
  • CDN
  • 으로부터 정적 제공 파일
  • 프런트엔드와 백엔드를 연결하는 GraphQL
  • 서버 없는 배포를 위한 AWS Lambdas
  • 단일gitpush 명령을 통해 배치
  • My dream of a future is for something I call a universal deployment machine, which means I write my code. It's all text, I just write text. Then I commit to GitHub. Then it's picked up and it's deployed into reality. That's it, that's the whole thing.

    Tom Preston Warner
    RedwoodJS Shoptalk (May 11, 2020)


    FaunaDB 회사


    FaunaDB는 서버가 없는 전역 데이터베이스로 낮은 지연과 개발자의 생산력에 사용하도록 설계되었다.전역적 확장성, 로컬 GraphQL API, FQL 조회 언어가 Jamstack 개발자에게 특히 매력적이라는 사실이 증명되었다.

    Being a serverless distributed database, the JAMstack world is a natural fit for our system, but long before we were chasing JAMstack developers, we were using the stack ourselves.

    Matt Attaway
    Lessons Learned Livin' La Vida JAMstack (January 24, 2020)


    이 문서에서는 RedwoodJS와 FaunaDB를 사용하여 응용 프로그램을 만드는 방법을 소개합니다.

    홍목 모노레포


    홍목 응용 프로그램 만들기


    우선, 우리는 Redwood CLI를 사용하여 처음부터 새로운 Redwood 응용 프로그램을 만들 것입니다.사선이 설치되지 않은 경우 다음 명령을 입력합니다.
    npm install -g yarn
    
    현재, 우리는 yarn create redwood-app 응용 프로그램의 기본 구조를 생성할 것이다.
    yarn create redwood-app ./redwood-fauna
    
    나는 이미 나의 프로젝트redwood-fauna에 전화를 걸었지만, 응용 프로그램의 이름을 마음대로 선택해 주십시오.현재, 우리는 cd 우리의 새로운 프로젝트를 도입하고, yarn rw dev 우리의 개발 서버를 시작할 것이다.
    cd redwood-fauna
    yarn rw dev
    
    우리의 프로젝트 전단은 localhost:8910, 후단은 localhost:8911 에서 GraphQL 조회를 받을 준비를 하고 있습니다.

    홍삼 목록 구조


    Redwood의 지도 사상 중 하나는 표준에 힘이 있기 때문에 어떤 기술을 사용하는지, 코드를 파일에 어떻게 구성하는지, 어떻게 명명할지 결정합니다.
    우리를 위해 창조한 모든 것을 봐라, 아마도 좀 당황스러울 것이다.우선 주목해야 할 것은 홍목 응용 프로그램은 두 개의 디렉터리로 나뉜다.
  • api 백엔드용
  • web 프런트엔드용
  • ├── api
    │   ├── db
    │   │   ├── schema.prisma
    │   │   └── seeds.js
    │   └── src
    │       ├── functions
    │       │   └── graphql.js
    │       ├── graphql
    │       ├── lib
    │       │   └── db.js
    │       └── services
    └── web
        ├── public
        │   ├── favicon.png
        │   ├── README.md
        │   └── robots.txt
        └── src
            ├── components
            ├── layouts
            ├── pages
                ├── FatalErrorPage
                │   └── FatalErrorPage.js
                └── NotFoundPage
                    └── NotFoundPage.js
            ├── index.css
            ├── index.html
            ├── index.js
            └── Routes.js
    
    모든 측은 코드 라이브러리에 자신의 경로를 가지고 있다.이것들은 Yarnworkspaces이 관리합니다.Fauna 클라이언트와 직접 대화를 나누면 db 디렉터리와 파일을 삭제할 수 있고 db.js 의 모든 코드를 삭제할 수 있습니다.

    페이지


    지금 응용 프로그램을 설정하면 우리는 페이지를 만들기 시작할 수 있습니다.우리는 generate page 명령을 사용하여 이 페이지를 저장하기 위해 홈페이지와 폴더를 만들 것입니다.우리는 generate 대신 g 을 사용하여 입력을 저장할 수 있다.
    yarn rw g page home /
    
    web/src/pages 디렉터리로 이동하면 HomePage 파일이 포함된 디렉터리를 볼 수 있습니다.
    // web/src/pages/HomePage/HomePage.js
    
    import { Link } from '@redwoodjs/router'
    
    const HomePage = () => {
      return (
        <>
          <h1>HomePage</h1>
          <p>Find me in "./web/src/pages/HomePage/HomePage.js"</p>
          <p>
            My default route is named "home", link to me with `
            <Link to="home">routes.home()</Link>`
          </p>
        </>
      )
    }
    
    export default HomePage
    
    우리 구성 요소를 정리합시다.우리는 현재 루트가 하나밖에 없기 때문에 가져오기 HomePage.jsLink 를 삭제할 수 있습니다. 우리는 단일 routes.home() 표시를 제외한 모든 내용을 삭제할 것입니다.
    // web/src/pages/HomePage/HomePage.js
    
    const HomePage = () => {
      return (
        <>
          <h1>RedwoodJS+Fauna</h1>
        </>
      )
    }
    
    export default HomePage
    

    세포


    단원격은 더욱 간단하고 성명적인 데이터 획득 방법을 제공했다.여기에는 GraphQL 쿼리, 로드, 비어 있음, 오류 및 성공 상태가 포함되며 각 상태는 셀이 있는 상태에 따라 자동으로 표시됩니다.<h1>web/src/components 라는 폴더를 만들고 이 폴더에 PostsCell 라는 파일을 만듭니다. 코드는 다음과 같습니다.
    // web/src/components/PostsCell/PostsCell.js
    
    export const QUERY = gql`
      query POSTS {
        posts {
          data {
            title
          }
        }
      }
    `
    
    export const Loading = () => <div>Loading posts...</div>
    export const Empty = () => <div>No posts yet!</div>
    export const Failure = ({ error }) => <div>Error: {error.message}</div>
    
    export const Success = ({ posts }) => {
      const {data} = posts
      return (
        <ul>
          {data.map(post => (
            <li>{post.title}</li>
          ))}
        </ul>
      )
    }
    
    데이터베이스에 있는 게시물을 가져오는 GraphQL 쿼리를 내보내고 있습니다.우리는 객체 분해를 사용하여 데이터 객체에 액세스한 다음 응답 데이터를 매핑하여 게시물 목록을 표시합니다.게시글 목록을 표시하려면 PostsCell.js 파일에서 PostsCell 을 가져오고 구성 요소를 되돌려야 합니다.
    // web/src/pages/HomePage/HomePage.js
    
    import PostsCell from 'src/components/PostsCell'
    
    const HomePage = () => {
      return (
        <>
          <h1>RedwoodJS+Fauna</h1>
          <PostsCell />
        </>
      )
    }
    
    export default HomePage
    

    모드 정의 언어

    HomePage.js 디렉토리에서 GraphQL 모드를 포함하는 graphql 라는 파일을 만듭니다.이 파일에서 GraphQL 모드 정의 언어를 포함하는 모드 객체를 내보냅니다.그것은 posts.sdl.js 유형을 정의했는데, 그 중에서 Post 유형은 title 유형이다.
    Flora는 자동으로 페이지를 나누기 위한 String 형식을 만듭니다. 이 형식의 데이터 형식은everyPostPage가 있는 그룹을 포함합니다.우리가 데이터베이스를 만들 때, 플로라가 우리의 GraphQL 조회에 어떻게 응답하는지 알 수 있도록 이 모드를 가져와야 합니다.
    // api/src/graphql/posts.sdl.js
    
    import gql from 'graphql-tag'
    
    export const schema = gql`
      type Post {
        title: String
      }
    
      type PostPage {
        data: [Post]
      }
    
      type Query {
        posts: PostPage
      }
    `
    

    데이터베이스


    프로젝트를 생성할 때 Post 기본값은 db 의 실례입니다.Prisma는 현재 Fauna를 지원하지 않기 때문에, 우리는 PrismaClient 라이브러리에서 Fauna의 GraphQL API를 조회할 것이다.우선 프로젝트에 라이브러리를 추가해야 합니다.
    yarn workspace api add graphql-request graphql
    
    GraphQL 노드를 통해 FaunaDB 데이터베이스에 접근하기 위해서는 데이터베이스 키를 포함하는 요청 헤더를 설정해야 합니다.
    // api/src/lib/db.js
    
    import { GraphQLClient } from 'graphql-request'
    
    export const request = async (query = {}) => {
      const endpoint = 'https://graphql.fauna.com/graphql'
    
      const graphQLClient = new GraphQLClient(endpoint, {
        headers: {
          authorization: 'Bearer <FAUNADB_KEY>'
        },
      })
      try {
        return await graphQLClient.request(query)
      } catch (error) {
        console.log(error)
        return error
      }
    }
    

    서비스


    서비스 디렉터리에 graphql-request 라는 파일을 포함하는posts 디렉터리를 만들 것입니다.서비스는 레드우드가 모든 업무 논리를 집중하는 곳이다.이러한 기능은 GraphQL API 또는 백엔드 코드의 다른 위치에서 사용할 수 있습니다.posts 함수는Fauna-GraphQL 단점을 조회하고posts 데이터를 되돌려주어 우리posts.js가 사용할 수 있도록 합니다.
    // api/src/services/posts/posts.js
    
    import { request } from 'src/lib/db'
    import { gql } from 'graphql-request'
    
    export const posts = async () => {
      const query = gql`
      {
        posts {
          data {
            title
          }
        }
      }
      `
    
      const data = await request(query, 'https://graphql.fauna.com/graphql')
    
      return data['posts']
    }
    
    Falla Shell에 대한 논의를 계속하기 전에 전체 디렉토리 구조를 살펴보겠습니다.
    ├── api
    │   └── src
    │       ├── functions
    │       │   └── graphql.js
    │       ├── graphql
    │       │   └── posts.sdl.js
    │       ├── lib
    │       │   └── db.js
    │       └── services
    │           └── posts
    │               └── posts.js
    └── web
        ├── public
        │   ├── favicon.png
        │   ├── README.md
        │   └── robots.txt
        └── src
            ├── components
            │   └── PostsCell
            │       └── PostsCell.js
            ├── layouts
            ├── pages
                ├── FatalErrorPage
                ├── HomePage
                │   └── HomePage.js
                └── NotFoundPage
            ├── index.css
            ├── index.html
            ├── index.js
            └── Routes.js
    

    동물군 데이터베이스


    FaunaDB 계정 만들기


    따라갈 계정이 필요하지만, 간단한 저유량 데이터베이스를 무료로 만들 수 있습니다.이메일로 계정을 만들거나 Github 또는 Netlify 계정을 사용할 수 있습니다.FaunaDB Shell은 현재 GitHub나 Netlify 로그인을 지원하지 않기 때문에 fauna Shell을 사용하여 인증을 하려고 할 때 이 로그인을 사용하면 추가 절차가 추가됩니다.
    우선, 우리는 터미널에서 우리의 데이터베이스를 쉽게 사용할 수 있도록 Fatura 셸을 설치할 것이다.너도 계기판에 들어가 Fanua의 웹 케이스를 사용할 수 있다.
    npm install -g fauna-shell
    
    셸을 사용하여 데이터베이스에 액세스할 수 있도록 Flora 계정에 로그인합니다.
    fauna cloud-login
    
    전자 메일과 비밀번호를 확인해야 합니다.GitHub 또는 Netlify 자격 증명을 사용하여 FaunaDB를 등록하는 경우 FaunaDB 를 따르고 "새 데이터베이스 만들기"섹션을 건너뛰고 "집합"섹션의 시작 부분에서 이 강좌를 계속합니다.

    이러한 단계 새 데이터베이스 만들기


    데이터베이스를 만들려면 PostsCell 명령을 입력하고 데이터베이스의 이름을 지정합니다.
    fauna create-database my_db
    
    우리의 새 데이터베이스로fauna셸을 시작하기 위해서, 우리는 fauna create-database 명령을 입력하고 데이터베이스의 이름을 따를 것입니다.
    fauna shell my_db
    

    가져오기 구조


    다음 코드를 sdl이라는 파일에 저장합니다.gql 및 데이터베이스 가져오기:
    type Post {
      title: String
    }
    type Query {
      posts: [Post]
    }
    

    소장하다


    우리의 데이터베이스를 테스트하기 위해서, 우리는 포스트라는 집합을 만들 것이다.데이터베이스의 모델은 그 집합에 의해 정의된다. 이 집합들은 다른 데이터베이스의 표와 유사하다.명령을 입력하면 fauna 셸은 새로 만든 fauna shell 으로 응답합니다.
    CreateCollection(
      { name: "Post" }
    )
    
    {
      ref: Collection("Post"),
      ts: 1597718505570000,
      history_days: 30,
      name: 'Post'
    }
    

    창조

    Collection 함수는 새 문서를 컬렉션에 추가합니다.첫 번째 블로그를 만듭니다.
    Create(
      Collection("Post"),
      {
        data: {
          title: "Deno is a secure runtime for JavaScript and TypeScript"
        }
      }
    )
    
    {
      ref: Ref(Collection("Post"), "274160525025214989"),
      ts: 1597718701303000,
      data: {
        title: "Deno is a secure runtime for JavaScript and TypeScript"
      }
    }
    

    지도.


    우리는 Create 함수를 사용하여 여러 개의 블로그 게시물을 만들 수 있다.우리는post수조와 Map 호출 Map 을 사용합니다. 이 수조는 Lambda 을 유일한 매개 변수로 합니다.그리고 post_title 에서 post_title 을 사용하여 새 직위마다 제목 필드를 제공합니다.
    Map(
      [
        "Vue.js is an open-source model–view–viewmodel JavaScript framework for building user interfaces and single-page applications",
        "NextJS is a React framework for building production grade applications that scale"
      ],
      Lambda("post_title",
        Create(
          Collection("Post"),
          {
            data: {
              title: Var("post_title")
            }
          }
        )
      )
    )
    
    [
      {
        ref: Ref(Collection("Post"), "274160642247624200"),
        ts: 1597718813080000,
        data: {
          title:
            "Vue.js is an open-source model–view–viewmodel JavaScript framework for building user interfaces and single-page applications"
        }
      },
      {
        ref: Ref(Collection("Post"), "274160642247623176"),
        ts: 1597718813080000,
        data: {
          title:
            "NextJS is a React framework for building production grade applications that scale"
        }
      }
    ]
    

    색인


    이제 컬렉션의 모든 게시물을 검색하는 색인을 만들 것입니다.
    CreateIndex({
      name: "posts",
      source: Collection("Post")
    })
    
    {
      ref: Index("posts"),
      ts: 1597719006320000,
      active: true,
      serialized: true,
      name: "posts",
      source: Collection("Post"),
      partitions: 8
    }
    

    성냥

    Lambda 색인에 대한 인용을 되돌려줍니다. 이 색인Index은 받아들이고 구조 집합에 사용됩니다.MatchPaginate에서 출력을 얻고 동물군에서 얻은 결과를 되돌려준다Match.여기서 우리는 인용수 그룹으로 돌아간다.
    Paginate(
      Match(
        Index("posts")
      )
    )
    
    {
      data: [
        Ref(Collection("Post"), "274160525025214989"),
        Ref(Collection("Post"), "274160642247623176"),
        Ref(Collection("Post"), "274160642247624200")
      ]
    }
    

    λ


    우리는 인용 그룹을 얻을 수 있지만, 인용에 포함된 실제 데이터 그룹을 원한다면?우리는 다른 프로그래밍 언어에서처럼 수조를 두루 돌아다닐 수 있다.
    Map(
      Paginate(
        Match(
          Index("posts")
        )
      ),
      Lambda(
        'postRef', Get(Var('postRef'))
      )
    )
    
    {
      data: [
        {
          ref: Ref(Collection("Post"), "274160525025214989"),
          ts: 1597718701303000,
          data: {
            title: "Deno is a secure runtime for JavaScript and TypeScript"
          }
        },
        {
          ref: Ref(Collection("Post"), "274160642247623176"),
          ts: 1597718813080000,
          data: {
            title:
              "NextJS is a React framework for building production grade applications that scale"
          }
        },
        {
          ref: Ref(Collection("Post"), "274160642247624200"),
          ts: 1597718813080000,
          data: {
            title:
              "Vue.js is an open-source model–view–viewmodel JavaScript framework for building user interfaces and single-page applications"
          }
        }
      ]
    }
    
    따라서 이제 우리는 하나만 사용할 수 있다.

  • 페이지 - Page

  • 셀 - Map

  • 기능 - HomePage.js

  • SDL-PostsCell.js

  • Lib-graphql.js

  • 서비스 - posts.sdl.js
  • Famila Shell에서 FQL 함수를 사용하여 데이터베이스를 만들고 데이터 피드를 추가합니다.FQL 기능은 다음과 같습니다.

  • CreateCollection - 컬렉션 생성

  • 만들기 - 컬렉션에서 문서 만들기

  • 매핑 - 함수를 모든 그룹 항목에 적용

  • Lambda - 익명 함수 실행

  • Get- 지정된 참조된 문서 읽어들이기

  • CreateIndex - 색인 생성

  • Match - 검색어와 일치하는 항목 집합 반환

  • Paginate- 집합이나 인용을 가져오고 결과를 한 페이지로 되돌려줍니다
  • 만약 우리가 홈페이지로 돌아간다면, 우리는 데이터베이스에서 게시물 목록을 가져오는 것을 볼 수 있을 것이다.

    우리도 db.js GraphiQL 운동장에 갈 수 있다.

    RedwoodJS는 백엔드의posts 서비스 조회 GraphQL API를 사용하고 있으며, 백엔드의PostsCell을 사용하여 데이터를 얻고 있습니다.만약 우리가 이 기능을 더욱 확장하고 싶다면, 우리는 패턴 정의 언어에 변체를 추가하고, GraphQL 클라이언트를 통해 완전한 CRUD 기능을 실현할 수 있다.
    RedwoodJS에 대해 더 알고 싶으면 FaunaDB 를 보거나 RedwoodJSdocumentation에 방문하십시오.우리는 당신들이 무엇을 건설하고 있는지 보고 매우 기꺼이 당신들의 어떤 질문에도 대답할 것입니다.

    좋은 웹페이지 즐겨찾기