일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- JUNCTION2023
- react
- framer-motion
- 글또
- TS
- 개발자 원칙
- 캐나다취준
- typescript
- 캐나다개발자
- Effective Typescript
- 타입스크립트
- 회고
- 개발자를 위한 글쓰기 가이드
- 코드트리
- ASP.NET
- CSS방법론
- 시스템디자인
- 이펙티브타입스크립트
- Framer motion
- VS Code
- 알고리즘
- Semantic Versioning
- JSBridge
- useState
- framer
- React-Router-Dom
- 글또 10기
- SemVer
- 테오의 스프린트
- CSS
- Today
- Total
큰 꿈은 파편이 크다!!⚡️
SSR 개발 중 만난 실전 디자인 패턴 PRG (ft. ASP.NET) 본문
살면서 위와 같은 팝업을 본 적이 있을 것이다. 오래 켜둔 페이지에 다시 들어가거나, 새로고침을 했을 때 주로 발생한다. 그리고 이러한 팝업에 불편함을 느끼는 사용자들도 있다.
이 글에서는 회사에서 ASP.NET을 개발하면서 만나게 된 이 Resubmit 문제와, 이를 해결하기 위한 디자인 패턴인 PRG 패턴에 대해 간단하게 설명하고, 어떻게 적용하는지에 대해 알아본 내용을 기록하고 있다.
😱 내가 겪은 문제
만들고자 하는 것
ASP.NET을 사용하는 웹사이트로 로그인 시도 시, 비밀번호를 몇 번 틀렸는지 알려주는 오류 메세지를 띄우고자 함.
사용자가 비밀번호를 잘못 입력하면 (POST)
서버에서 “비밀번호를 1회 틀렸습니다” 라는 문구와 함께 페이지를 새로 그려냄. (이것을 Content를 반환한다고 표현한다)
문제
문제는, 이미 비밀번호를 한 번 틀린 상황에서 새로고침을 하면,
페이지를 다시 불러오면서 폼이 한번 더 제출되고 (POST)
서버에서 “비밀번호를 2회 틀렸습니다” 라는 문구와 함께 페이지를 새로 그려낸다.
사용자는 로그인 시도를 다시 하지도 않았는데 비밀번호 오류 카운트가 올라가는 불상사를 맞게 된다.
추가 작업을 하여 비밀번호 오류 카운트를 올리지 않더라도 다시 POST를 하여 불필요하게 API를 호출하는 것은 사실이고, “양식 다시 제출 확인”과 같은 팝업이 자동으로 뜨면서 사용자 경험에도 좋지 않은 영향을 준다.
왜 이런 문제가 일어나나? with ASP.NET
SSR에서는, POST api를 호출하면 서버가 작업을 수행한 뒤 결과와 함께 html 페이지를 다시 만들어 반환하는데, 이는 새로고침(Refresh)하는 것과 같은 모습이 된다.
ASP.NET 코드를 예로 들어보겠다.
ASP.NET에서 사용하는 .cshtml
에서는 Razor 라는 문법으로 html 페이지와 관련 동작을 구현한다.
example.com이라는 url을 가진 페이지에 POST api를 호출하는 어떤 폼과 버튼이 있다고 생각해보자. 이 중에서 View를 누르면 누른 횟수를 세는 api로 연결된다.
<!-- Example.cshtml -->
<form asp-page-handler="view" method="post">
<input type="hidden" asp-for="@Model.Count" />
<button class="btn btn-default">View</button>
</form>
asp-page-handler="view"
를 통해, 코드 비하인드인 .cshtml.cs
의 onPostView
라는 api를 호출하는데, 결국 폼을 POST하기 위해 페이지 url이 example.com/view 로 변경된다.
//Example.cshtml.cs
//onPostView는 Razor문법의 prefix 컨벤션에 따른 이름이다
public void OnPostView(int count)
{
Count = count + 1;
Message = "View handler fired";
}
그렇다면 저 버튼을 누름으로써 우리는 example.com/view 페이지로 이동하게 된다. 다시말해 이 url은 view라는 asp.net의 핸들러를 부르는 url이다. 이 상태에서 새로고침을 하면? 당연히 view가 불리고 OnPostView api는 다시 호출되는 것이다.
🤟 PRG 패턴: Post-Redirect-Get
이 문제를 해결하는 것이 바로 Post-Redirect-Get 패턴이다.
호출된 POST api는 Get을 호출하는 페이지로 Redirect하는 결과를 반환한다. Get을 호출하는 페이지에서는 아무리 새로고침을 해도 여전히 Get이다.
내 문제에 PRG 패턴을 발라보자 in ASP.NET
POST api에서 이제는 GET으로 Redirect를 시켜주며, 이때 페이지를 구성하는데 필요한 값들을 함께 전달한다.
//Example.cshtml.cs
public IActionResult OnGet(int? count)
{
if (count != null)
Count = count;
Message = "View handler fired";
return Page();
}
public IActionResult OnPostView(int count)
{
Count = count + 1;
Message = "View handler fired";
return RedirectToPage("/Example", new() { count = Count; });
}
| 이 코드에서 RedirectToPage("/Example" ..)에서 “/Example”은 사이트의 URL이 아니라 Get하려는 함수가 있는 파일의 이름이다.
POST 후, api는 Redirect를 반환하며 example.com 로 돌아왔다. 그렇다면 여기에서 새로고침을 해도 여전히 example.com 이며 Resubmit 문제는 나타나지 않게 된다.
맺으며
검색하다보니 웹 개발을 위한 디자인 패턴 같은것도 있다는것을 알았고 공부할 게 또 늘었군^^ 하는 생각도 들었다. 이런식으로 실전에 적용해보는 것을 기반으로 하는 디자인 패턴 시리즈를 연재해보고 싶다.
이 글은 디자인 패턴과 ASP.NET을 동시에 설명하고 있다. 회사에서 ASP.NET을 가끔 작업하는데, 자료가 적고 SSR이 문제인건지 기술이 문제인건지.. 마음에도 안들고 자료도 적다고 느껴져 어렵긴 하지만.. SSR을 조금씩 배워가는 느낌이라 즐겁게^_^ 해보려고 하고, ASP.NET을 검색하면 자료가 하나라도 더 나오길 바라는 마음에서 작성했다.
Reference
'Web FE' 카테고리의 다른 글
리액트의 철학 (0) | 2023.05.07 |
---|---|
리액트 성능 향상 첫걸음: useMemo, useCallback, React.memo (0) | 2023.03.12 |
리액트 앱 배포 후 Cache 문제 🧹 삽질기 (0) | 2023.02.26 |
이펙티브 타입스크립트 🦅 2장 (3) (0) | 2022.10.08 |
이펙티브 타입스크립트 🦅 2장 (2) (0) | 2022.09.28 |