전자 우편 구독 프로그램 구축 - 제3부분: 백엔드 만들기

개술


이 강좌는 세 부분으로 구성되어 있으며, Zustand를 사용하여 구성 요소 단계에서 상태 관리를 하는 방법을 상세하게 소개할 것이다.Zustand를 전술적으로 사용하는 방법과 함께 완전히 통합된 React 구성 요소를 만드는 방법을 보여 드리겠습니다.
다음은 전체 시리즈에 포함될 내용을 세분화한 것입니다.
  • Part 1A: Creating a foundational React component
  • Part 1B: Adding a skeleton loader
  • Part 2: Connecting Zustand for fluid state management
  • Part 3: Connecting backend logic and microservice data resources
  • 경고로서, 편의를 위해, 위의 모든 부분은 코드 샌드박스에 연결되어 있으며, 이 부분의 완전한 코드를 포함한다.본 강좌를 공부할 때 시간을 충분히 이용하기 위해서, 우리는 이 절의 시작 부분의 단독 옵션 카드에서 부품의 모래상자를 열고 갈라놓는 것을 권장합니다.우리의 코드 샌드위치 예는 당신의 목표 환매일 수 있습니다.이 강좌의 모든 부분을 완성할 때, 목표는 최종적으로 목표와 비슷한 코드를 작성하는 것입니다.

    선결 조건


    이 섹션의 전제 조건은 Part 1과 같습니다.

    우리의 목표


    이 부분을 통해, 우리는 10분도 안 되는 시간 안에 건장하고 확장 가능한 백엔드를 우리의 아침 식혜 복제품에 연결하기를 희망한다.

    편집기에서 새 도안 만들기


    동적 내용의 조회를 처리하고 단서를 저장하고 이메일을 보낼 메뉴를 만들 것입니다.이를 위해서는 개발자 패널을 구축할 수 있는 Recipe 옵션 카드에 들어가 새로운 Recipe을 만들고 이름을 붙여야 한다.

    If you don't already have an account @ Buildable.dev request an invite code



    트리거 설정


    트리거 단계에서 우리는 도안의 권한을 닫고 두 개의 입력 파라미터를 추가할 것이다.
  • key - 선택 사항이 아닌 문자열
  • email - 이메일 옵션
  • 또한 다음과 같은 예제 유효 로드를 제공합니다.
    {
      "key": "content"
    }
    
    완료되면 최종 트리거 단계는 다음과 같습니다(끝점 URL은 다릅니다).
    https://uploads-ssl.webflow.com/5f6b9731fe02400ffade5b26/602ae92e28b6c66653bb4a76_Screen_Shot_2021-01-25_at_6.07.57_PM.png

    조건 단계 추가


    단계 아래의 "+"기호를 트리거하고 단계 선택기에서 조건 옵션을 선택하여 레시피에 조건 라우트를 추가합니다.조직을 위해 식단의 한 걸음 한 걸음 뚜렷한 이름을 붙이는 것이 좋다.이 예에서는 이 단계를 기준 단계라고 부릅니다. isContent

    당신의 조건을 설정합니다


    우리는 조건 논리를 추가하여 이 메뉴가 내용을 되돌려줄지, 제출을 기대할지 구분할 것입니다.
    먼저 YES 라우팅으로 단계가 분할되는 시기를 지정하는 규칙을 추가합니다.다시 말하면 다음과 같은 규칙을 충족시킬 때 우리는 조건의 왼쪽으로 가기를 희망한다. $steps.trigger.key에'콘텐츠'가 포함되어 있다.

    조건 논리 추가


    이 YES 분기에 함수 절차를 추가하고 함수를 '콘텐츠' 라고 명명할 것입니다.코드 세그먼트 섹션에서는 다음 코드를 삽입합니다.
    const content = {
      title: "Become smarter in just 6 minutes",
      subTitle:
        "You're now witnessing the power of a fully dynamic component 🤯",
      input: {
        id: "email-input",
        type: "email",
        label: "Enter your email",
        placeholder: "Enter your email",
        variant: "outlined"
      },
      errors: {
        invalidEmail: "We require a valid email",
        empty: "Email is required please"
      },
      button: {
        states: {
          initial: "Submit",
          processing: "Sending request",
          success: "Sent successfully",
          failed: "Failed! Try again."
        }
      }
    };
    
    const onRun = () => {
    
      return {
        ...content
      };
    
    };
    
    주의해야 할 것은 콘텐츠 변수는 설정 중fallback.js 파일의 콘텐츠 변수와 같다는 것이다Part 2 for more information.
    현재의 레시피는 다음과 같다.

    이제 YES 분기에 응답 단계를 추가합니다.우리는 우리의 응답 절차를 '내용 응답' 이라고 명명할 것이다.이 단계에서는 상태 코드를 200OK로 유지합니다.응답 단계에서 레시피를 끝내고 단계 주체를 클라이언트에게 되돌려줍니다.응답 단계에 대한 자세한 내용은 Buildable's Documentation on Responses를 참조하십시오.
    우리는 또한 이전 함수 단계의 데이터를 전파할 것이다.이를 위해 키 값 __spread__ 을 추가하고 $steps.is-content.pass.content.data 을 값으로 선택할 것입니다.이 변수를 추가하는 간단한 방법은 내용을 입력하는 것입니다.표시된 사용 가능한 옵션을 클릭합니다.데이터를 올바르게 전달하는 방법에 대한 자세한 내용은 Buildable's Documentation on How to Pass Data between Steps를 참조하십시오.

    당신의 레시피는 지금 이렇게 해야 합니다.

    빠른 테스트 레시피를 통해 모든 것이 정상인지 확인합시다.테스트를 실행하려면 편집기의 오른쪽 상단에 있는 테스트 레시피 단추를 누르십시오.테스트를 실행할 때, 트리거 절차를 검사해서 적당한 출력을 확보하십시오.아래 출력을 보시면 레시피 테스트가 성공합니다!

    Leads 서비스 작성


    현재 우리는 조건의 YES지점을 완성했고 NO지점을 처리하기 시작할 것이다.우선, Google은 귀하의 마이크로서비스 생성기를 사용하여 Leads 서비스를 만들 것입니다.대시보드를 구축할 수 있는 서비스 탭으로 이동하여 Leads라는 서비스를 만듭니다.여기에서, 우리는 전자 우편 수집 구성 요소에 전자 우편을 입력한 모든 사용자를 위해 데이터를 저장할 것이다.

    Leads 서비스를 만든 후에는 이제 레시피 편집기에서 액세스할 수 있습니다.레시피의 기준 단계로 돌아가서 다음을 수행합니다.
  • 조건문의 NO 지점에 서비스 절차 추가
  • 첫 번째 드롭다운 목록에서 Leads 서비스
  • 를 선택합니다.
  • 두 번째 드롭다운 목록에서 때 만들기 작업 선택
  • 메뉴의 서비스 단계를 클릭하면 서랍의 내용이 다음과 같이 표시됩니다.

    이 때 이 지점이 점용되면 빈 잠재 고객 기록을 만들 것입니다.다음은 빈 잠재 고객 기록이 필요하지 않기 때문에 트리거에 예시적인 유효 부하를 적용함으로써 모든 잠재 고객 기록에 유용한 데이터가 포함되어 있음을 확보합니다.우리는 아래에서 이 점을 소개할 것이다.

    트리거 단계에서 사용자 제출을 시뮬레이션하기 위해 유효 부하를 변경합니다


    우리는 사용자가 프로그램에서 전자메일을 제출할 때 이 지점을 사용할 수 있도록 NO 지점을 실행하기를 희망합니다.필드에 e-메일을 추가하고 제출 버튼을 클릭하면 사용자의 e-메일을 캡처하여 Leads 서비스에 저장하고자 합니다.
    우선 촉발 단계로 돌아간다.이를 바탕으로 다음 단계에 따라 유효 부하를 조정합니다.
    {
      "key": "submission",
      "email": "[email protected]"
    }
    
    유효 부하를 추가한 후, NO 지점이 우리가 예상한 대로 작동하는지 확인하기 위해 다시 설계도를 테스트합니다.편집기의 오른쪽 상단에 있는 테스트 레시피를 누르면 조건 단계 결과를 열 수 있습니다.실행 지점이 탭이 없는 경로라는 것을 알 수 있습니다.

    완료되면 서비스 단계로 돌아가서 Lead CRUD 생성 작업에 포함할 데이터를 추가합니다.이런 상황에서 그것은
  • email - $steps.trigger.email
  • ip - $steps.recipeHeaders.x-forwarded-for
  • country - $steps.recipeHeaders.cf-ipcountry

  • NO 분기를 실행하면 레시피가 전자 메일, IP 및 국가 레코드를 생성합니다.이 식단은 전자메일의 독특성을 처리할 수 없다는 것을 명심하세요.이것은 도안 편집기를 사용해서 해결할 수 있지만, 간단하게 보기 위해서, 우리는 그것을 건너갈 것이다.

    전체 테스트를 실행하여 테스트 데이터 만들기


    모든 동작을 보기 위해서, 제출한 메뉴를 호출하고 생성된 잠재적 고객 기록을 볼 것입니다.
    먼저 잠재적 고객 서비스 생성 단계를 시작하여 "테스트 실행 시 이 작업 일시 중지"를 닫습니다.전환하다.테스트를 실행하고 일시 중지 전환을 열린 상태로 되돌려줍니다.

    테스트를 실행할 때 이 동작을 일시 중지하시겠습니까?전환 기능은 서비스 단계를 사용하여 여러 테스트를 수행할 때 유용합니다.이것은 예상을 초과한 데이터를 잘못 만들지 않도록 하는 데 도움이 될 것입니다.
    여기서부터 우리는 Lead 서비스에 Lead 기록이 존재하기를 기대해야 한다. 그러므로 우리는 우리의 서비스를 검사할 것이다.대시보드를 구성할 수 있는 서비스 탭으로 돌아가 Leads 서비스를 클릭합니다.이제 저희가 전달한 데이터와 함께 기록이 존재한다는 것을 알게 될 것입니다.

    우리의 설계도와 우리의 구성 요소를 연결하다


    Axios를 사용하여 어셈블리에서 HTTP 요청을 보냅니다.React 응용 프로그램으로 이동하여 logic 폴더에 api.js라는 새 파일을 추가합니다.이 파일에 다음 코드 세그먼트를 추가합니다.
    import axios from "axios";
    
    const POST = "POST";
    
    const config = {
      recipeUrl: "https://api.buildable.dev/trigger",
      recipeEnv: process.env.NODE_ENV === "development" ? "test" : "live",
      version: "v2"
    };
    
    const { recipeUrl, recipeEnv, version } = config;
    
    const api = async ({ payload, url, headers = {} }) => {
      const { data } = await axios({
        method: POST,
        url,
        headers,
        data: payload
      });
    
      return data;
    };
    
    const dispatchRecipe = ({ triggerId, payload = {}, options = {} }) =>
      api({
        ...options,
        url: `${recipeUrl}/${version}/${recipeEnv}-${triggerId}`,
        payload
      });
    
    export default dispatchRecipe;
    
    위 코드 세그먼트에서 Axios 주변에 작은 패키지를 만들어 보다 쉽게 레시피를 배포할 수 있도록 했습니다.이제 data-models.js 파일로 이동하고 api.js 파일에서 디스패치 Recipe를 가져옵니다.다음 코드 세그먼트 업데이트 getContent 방법 (initContent Model 내부) 을 사용해야 합니다.
    getContent: async () => {
        const payload = {
          key: "content"
        };
        const content = await dispatchRecipe({
          triggerId: RECIPES.LEADS_BLOCK,
          payload
        });
        set((state) => ({ ...state, content }));
      },
    
    전체 업데이트 파일은 다음과 같습니다.
    import { content } from "../fallback";
    import dispatchRecipe from "./api";
    
    const RECIPES = {
      LEADS_BLOCK: "YOUR_RECIPE_TRIGGER_ID"
    };
    
    const initContentModel = (set) => ({
      content,
      currentButtonText: content.button?.states?.initial,
      setButtonText: (buttonText) =>
        set((state) => ({ ...state, currentButtonText: buttonText })),
      getContent: async () => {
        const payload = {
          key: "content"
        };
        const content = await dispatchRecipe({
          triggerId: RECIPES.LEADS_BLOCK,
          payload
        });
        set((state) => ({ ...state, content }));
      },
      setContent: (content) => {
        set((state) => ({ ...state, content }));
      }
    });
    
    const initLoadingModel = (set) => ({
      loading: false,
      processing: false,
      setLoading: () => {
        set((state) => ({ ...state, loading: true }));
      },
      clearLoading: () => {
        set((state) => ({ ...state, loading: false }));
      },
      setProcessing: () => {
        set((state) => ({ ...state, processing: true }));
      },
      clearProcessing: () => {
        set((state) => ({ ...state, processing: false }));
      }
    });
    
    export { initContentModel, initLoadingModel };
    
    
    그리고 트리거 ID를 트리거 Id 필드에 복사해서 붙여야 합니다.트리거 ID를 찾으려면 레시피의 트리거 단계를 클릭하면 됩니다.

    메뉴의 triggerId를 찾은 후 코드 세그먼트에 넣으면 "YOUR Recipe triggerId"를 볼 수 있습니다.

    getContent 흐름 만들기

    components/email-block/logic/flows.js로 이동하여 파일을 다음과 같이 업데이트합니다.
    import { useStore } from "./store";
    import { content as fallbackContent } from "../fallback";
    
    const wait = async (time) =>
      new Promise((resolve) => setTimeout(() => resolve(true), time));
    
    const useDispatchEmailFlow = () => {
      const [
        setProcessing,
        clearProcessing,
        setButtonText,
        buttonStates
      ] = useStore((store) => [
        store.setProcessing,
        store.clearProcessing,
        store.setButtonText,
        store.content?.button?.states
      ]);
    
      const dispatch = async () => {
        setProcessing();
        setButtonText(buttonStates?.processing);
        await wait(2000);
        setButtonText(buttonStates?.success);
        await wait(1000);
        setButtonText(buttonStates?.initial);
        clearProcessing();
      };
      return dispatch;
    };
    
    const useDispatchGetConentFlow = () => {
      const [
        setLoading,
        clearLoading,
        getContent,
        setContent
      ] = useStore((store) => [
        store.setLoading,
        store.clearLoading,
        store.getContent,
        store.setContent
      ]);
    
      const dispatch = async () => {
        setLoading();
        try {
          await getContent();
        } catch (error) {
          setContent(fallbackContent);
        }
        clearLoading();
      };
      return dispatch;
    };
    
    export { useDispatchEmailFlow, useDispatchGetConentFlow };
    
    이 파일에서 useDispatchGetContentFlow를 만들고 있습니다.
  • 설계도
  • 에서 동적 내용 얻기
  • 동적 내용을 추출할 수 없는 경우
  • fallback.js이제 구성 요소에서 이 데이터를 요청합시다.EmailBlock.js 파일에서useDispatchGetContent Flow를 가져오고useEffect에서 호출합니다.EmailBlock.js 파일을 다음과 같이 업데이트합니다.
    import React, { useEffect } from "react";
    import { Box, Text, Heading } from "grommet";
    import { TextField } from "@material-ui/core";
    import theme from "../../theme";
    import Button from "./Button";
    import LoadingBlock from "./LoadingBlock";
    import { useStore } from "./logic/store";
    import { useDispatchEmailFlow, useDispatchGetContentFlow } from "./logic/flows";
    
    const { colors } = theme;
    
    const WrapperBox = ({ children }) => (
      <Box
        elevation={"large"}
        width={"500px"}
        round="8px"
        background={colors.white}
        pad={"large"}
        gap={"medium"}
      >
        {children}
      </Box>
    );
    
    const EmailBlock = () => {
      const [isLoading, isProcessing] = useStore((state) => [
        state.loading,
        state.processing
      ]);
    
      const [content, currentButtonText] = useStore((state) => [
        state.content,
        state.currentButtonText
      ]);
    
      const dispatch = useDispatchEmailFlow();
      const getContent = useDispatchGetContentFlow();
    
      useEffect(() => {
        getContent();
      }, []);
    
      return (
        <>
          {isLoading && (
            <WrapperBox>
              <LoadingBlock />
            </WrapperBox>
          )}
          {!isLoading && (
            <WrapperBox>
              <Heading level={1} color={colors.black}>
                {content.title}
              </Heading>
              <Text size={"medium"}>{content.subTitle}</Text>
              <TextField {...content.input} />
              <Button
                type="submit"
                onClick={(e) => {
                  e.preventDefault();
                  dispatch();
                }}
                disabled={isProcessing}
                background={colors.primary}
                color={colors.white}
                style={{
                  paddingTop: "16px",
                  paddingBottom: "16px"
                }}
              >
                {currentButtonText}
              </Button>
            </WrapperBox>
          )}
        </>
      );
    };
    
    export default EmailBlock;
    

    결론


    축하합니다!웹 응용 프로그램 배치에 필요한 모든 작업을 완료했습니다.이 시리즈의 이 부분에서 당신은 전체 웹 응용을 위해 어떻게 마이크로 서비스 체계 구조와 백엔드 논리를 구축하는지 배웠습니다.우리는 함수, 조건, 응답 절차를 사용하여 실현한다.
    자신의 시간에 SendGrid 전자 우편 절차를 추가하여 전자 우편을 제출한 모든 사용자에게 전자 우편을 보낼 수도 있습니다.e-메일 트리거를 연결하는 방법에 대한 자세한 내용은 Buildable's SendGrid Integration documentation를 참조하십시오.
    응용 프로그램의 코드Code Sandbox를 위에서 찾을 수 있습니다.

    좋은 웹페이지 즐겨찾기