블레이저 용어

요즘 블레이저 관련한 글들이 점차 늘어 나고 있는 것 같습니다.

그런데, 용어가 약간 씩 섞여 있는 느낌이라, 몇 가지 정리를 해봤습니다.

레이저 (Razor)

비 html 소스 코드를, html 문서에 삽입하는 문법을 가리킵니다. ‘@’ 가 식별 마크로 사용됩니다.

닷넷 사용자 입장에서는 이 문법을 통해 html 문서에 C# 코드만 삽입할 수 있는 것으로 생각하시겠지만, 사실 특정 언어에 종속되지 않은 기술입니다.

파서만 정의하면, 얼마든지 다른 언어에도 적용이 가능한데, 마소가 안 할 뿐이죠. (하면 배신입니다)

레이저 페이지(.cshtml)

레이저 문법을 통해 C# 코드가 삽입된 html 문서입니다. C#-Razored Html Document 이 가장 적정한 표현일 것 같습니다.

레이저 요소(.razor)

흔히들 "블레이저 요소"로 언급하는 경우가 많으나, 공식 명칭은 “Razor Component” 입니다.
레이저 컴포넌트는 레이저 문법으로 선언한 커스텀 html element 이라 할 수 있는데, 레이저 페이지와 형태적으로는 동일하지만 재사용성을 강화시킨 것입니다.
C#-Razored Html Element 이 가장 적정한 표현일 것입니다.

레이저 요소는 html 요소이기에, 당연히 html 문서에서 사용될 수 있고, html 문서에는 레이저 페이지도 포함됩니다.

이름이 말해주듯, 요소이기 때문에, 가급적 작게 작게 정의해서 여러 프로젝트에 두루 두루 쓸 수 있도록 하는 것이 좋습니다. 이를 위해서 레이저 라이브러리 프로젝트가 있습니다.

블레이저 (Blazor)

화면을 갱신하는 게 주 임무인 자바 스크립트가 요체입니다.

블레이저 웹어셈블리
wwwroot/_framework/blazor.webassembly.js

함께 다운로드되는 Webassembly 바이너리와 데이터를 주고 받는데, Webassembly가 C# 코드를 실행시킵니다. 즉, 프로젝트에 삽입된 실행 코드는 사용자 PC의 브라우저에서 실행됩니다.

보시다시피, 블레이저 웹어셈블리는 전통적인 프론트 엔드의 실행 방식과 유사한데, 웹어셈블리를 실행하는 일반적인 방식합니다.

다만, 코드 작성 방식에 있어서, 전통적인 프론트 엔드와 차이점이 있습니다.

전통적인 프론트 엔드 코드는 그 자체로 로컬에서 실행 가능한 형태입니다.
그러나, 블레이저 웹 어셈블리는 실행에 필요한 파일(Webassembly 바이너리 포함)들을 프레임워크가 가지고 있는데, 서버에서 배포되는 시나리오만 지원합니다.

그냥 로컬에서 소스 코드 작성하고, 블레이저 개발 도구가 파일들을 프로덕션만 해주면, 바로 로컬에서 실행해 볼 수 있는데 말이죠. 이 경우 핫리로드도 필요 없습니다. 브라우저만 새로고침하면 되니까요.

(혹시 이렇게 하는 방법을 알고 계신 분이 있다면, 댓글 달아 주세요)

블레이저 서버
blazor.server.js

SignalR(웹소켓)을 통해 서버와 데이터를 주고 받습니다.

즉, 프로젝트에 삽입된 실행 코드는 서버에서 실행됩니다.
이는, 변수 하나라도 모두 서버에 저장되어 있음을 의미합니다.

닷넷 문서에서는 이를 "stateful"하다고 표현하는데, 상태(state)는 웹소켓이 끊어지지 않는 한 유지됩니다.
웹소켓(SignalR)의 개시부터 종료까지의 기간을 “circuit” 이라고 부르는데, 이는 웹 프로그래밍에서 일반적으로 사용되던 용어인 유저 세션, TCP/IP(Http) 세션들과 구분하기 위한 것입니다.

써킷을 기반하다 보니, 블레이저에서는 상태 관리(state management)가 중요합니다.
블레이저 (서버 스크립트) 자체는 웹소켓을 통해 서버에 보관된 상태와 실시간으로 동기화되지만, 이 상태를 바탕으로 UI 동기화는 자동으로 되지 않기 때문입니다.

이는 MVVM 에서 PropertyChanged 이벤트가 호출되지 않으면 뷰가 업데이트 되지 않는 것과 동일한 이치입니다.

그러나, 거의 대부분의 시나리오에서는 자동으로 통지되게끔 설계되었는데, 수동으로 처리해줘야 할 경우가 있습니다. 문제는, 수동 처리 케이스에 공교롭게도 인증과 관련한 케이스가 포함된다는 것이죠.

프로젝트 템플릿에 포함된 코드는 이런 부분에 관한 보완책이 있지만, 커스텀 인증을 구현하는 경우 이부분에 대한 대책을 마련하는 것이 좋습니다.

블레이저 서버 프로젝트는 Asp.Net Core의 다른 UI 프레임워크처럼, full stack 코드로 짭니다.

참고로, 전통적인 웹 프로그래밍에서는 프론트 엔드와 백엔드는 별개의 앱이기 때문에, (동일 시스템에서 실행되더라도) Http 프로토콜로 통신을 하지만, 풀스택 코드는 둘 사이에 Http 통신을 위한 코드가 존재하지 않기 때문에, 코드의 구조와 구현이 간단합니다.

프로젝트 디자인 가이드

전통적인 웹 프로그래밍 방식에서는 프론트엔드와 백엔드가 각각 작성됩니다.

여기에 익숙한 분들 중에, 블레이저 프로젝트를 생성할 때 습관적으로 웹 API 프로젝트를 생성하는 경우가 있는데, 사실 그렇게 할 필요는 없습니다.

블레이저 서버

블레이저 서버 앱은 Asp.Net Core 를 기반하는데, 이는 모체가 웹 API 프레임워크입니다.
레이저 요소를 통해 UI를 제공하는 것도, 웹 API를 통해 데이터를 제공하는 것도 단일 앱에서 구현 가능합니다.

따라서, 시스템 구조 상 반드시 필요한 경우가 아니라면, 웹 API를 추가하는 것은 설계 오류거나 자원의 낭비일 확률이 높습니다.

블레이저 웹어셈블리

웹어셈블리 프로젝트와 웹API 프로젝트를 결합하는 경우도 있는데, 웹 어셈블리의 코드의 테스트 목적이 아니라면, 블레이저 서버를 선택해서 풀스택으로 개발하는 게 더 효율적입니다.

블레이저 웹어셈블리는 이미 운영 중인 백엔드나 API에 접속하기 위한 프론트 엔드를 작성할 때 가장 적합합니다. 즉, 닷넷이 가장 빈약했던 분야인 프론트 엔드를 위한 기술입니다.

한계

현대 프로그래밍에서 웹의 비중은 누구도 무시하지 못합니다.
아시다시피, 웹 프로그래밍은 프론트엔드와 백엔드로 구별됩니다.

그런데, 백엔드 서비스나 클라우드 서비스들이 클릭 몇 번으로 백엔드를 구성하고 운영할 수 있도록 발전하고 있습니다. 거기에 점점 저렴해지기까지 하고 있죠.

이러한 환경은 백엔드를 자체 개발하는데 소요되는 기회 비용을 높여 놨고, 그 결과로 벡엔드 기술의 수요 또한 줄어 들었다고 할 수 있습니다. 여담이지만, 그 결과로 그 많던 소비자 용 워크스테이션들이 사라졌겠죠.

그런데, 닷넷은 이러한 환경에 반하는 풀스택 웹앱 도구에 집중해 왔고 이러한 경향은 블레이저 서버까지 유지되어 왔고, 앞으로도 계속 될 것 같습니다.

즉, 인기가 없는 개발 방식을 위한 개발 도구에 집중하고 있는 것이죠.
VS, 윈도우, SQL 서버 등을 팔아야 하기에.

여기에, 프론트 엔드 기술을 등한 시 해왔습니다. 그나마, 이제 막 블레이저 웹어셈블리가 나왔지만, 웹어셈블리를 기반하기에 초기 로딩 시간이 길어 사용자 경험이 좋지 못합니다. 요즘 같은 세상에 로딩 다이얼이라니…

물론, 레이지 로딩과 같은 보충 기술이 있으나, 보충은 보충일 뿐, 전통적인 프론트 엔드의 성능에 비빌 수준은 아닙니다.

닷넷의 풀스택은 비싸고, 프론트 엔드는 사용자 경험이 좋지 못하다는 약점이 있습니다.

닷넷이 풀스택에 대한 집착을 버리고, 좀 더 경쟁력 있는 프론트 엔드 기술을 발표하지 않는 한 닷넷의 전반적인 부진은 개선되지 않을 것입니다.

만약, 닷넷이 전통적인 프론트 엔드의 약점 - 낮은 시스템 자원 활용 능력 - 을 보완해주기만 한다면, 정말 매력적인 도구가 되지 않을까 합니다.

16개의 좋아요

와 스퀘어님은 blazor에 진심이시네요 이러다가 국내에 얼마없는 블레이저 대가 되실듯

7개의 좋아요

저도 그렇게 되면 좋겠습니다.
근데 밑천이 워낙 없어서… ㅠㅠ

4개의 좋아요

저도 골수 데탑앱…웹린이로서 블레이저에 대한 니즈가 계속 있는데 나중에 좋은 레퍼런스가 될 거 같습니다

감사합니다!

4개의 좋아요

Blazor Server 기술이 정말 매력적이죠.
http요청/응답에 대한 신경을 안써도 되기 때문에 웹풀스택을 하면서도 하나의 어플리케이션을 만드는 식으로 만들수있는게 너무 좋은데
연결에 대한 걱정을 하다보면 또 막 적용하기가 어렵네요

4개의 좋아요

글 수정했습니다. 쓰다 보니 헛소리를 적었더라구요. ^^

3개의 좋아요

레이저 페이지에서 레이저 요소를 쓸 수 있습니다.

사실 둘은 동일한 것입니다.
블레이저는 웹페이지 렌더러의 파생 객체 같은 느낌이 있습니다.

1개의 좋아요

레이저 페이지와 요소가 동일하다는 의미는 외형적(문법적)으로 동일하다는 의미입니다.
물론 생명 주기는 다릅니다.

Asp.Net Core Identity가 적용된 블레이저 서버 템플릿 코드를 보신 듯 하네요.

블레이저의 인증 처리의 핵심 객체는 페이지나 요소가 아니라, AuthenticationStateProvider 입니다.

Asp.Net Core Identity 가 블레이저 서버 프로젝트에 적용되면, 이 객체에 대한 조작을 레이저 페이지에서 수행하도록 설정한 것 뿐입니다. 이 방식을 사용하는 것이 가장 간편하고 믿음직스럽지만, 블레이저 서버의 인증을 위한 유일한 방법은 아닙니다.

Blazor JWT 인증/권한 예제 - :man_teacher: 튜토리얼, 팁, 강좌 - 닷넷데브 (dotnetdev.kr)

보시면, Asp.Net Core Identity 을 사용하지 않고, AuthenticationStateProvider를 직접 구현하여 인증을 자체적으로 처리하고 있습니다. (Login.razor 는 단순히 그 객체의 소비자일 뿐입니다.)

위 글의 방식도 사용할 수 있고, 인증 미들웨어를 통해 인증을 처리하고, 그 결과물(HttpContext)만 AuthenticationStateProvider 구현 객체에 주입하여 로그인을 구현하는 방법도 사용할 수 있습니다.(만 닷넷에서 추천하는 방식은 아닙니다)

2개의 좋아요

토론을 하면서 서로 의견이 맞지 않을 수는 있지만, 공격적인 태도로 토론에 임하는 것은 바람직하지 않다고 생각합니다.

  • 당신이 존중받기 원한다면, 상대방도 존중해주세요. 모두가 동시에 합의에 이르게 되지는 않습니다. 그러나, 의견의 불일치가 형편없는 행동이나 매너에 대한 변명이 될 수는 없습니다. 우리는 모두 이따금씩 좌절을 겪게 될 수 있습니다. 그러나, 좌절로 인해 개인적인 공격을 해도 되는 것은 아닙니다. 사람들이 불편해하거나 위협을 느끼는 커뮤니티는 생산적인 커뮤니티가 될 수 없다는 점을 기억해두는 것이 중요합니다. 우리는 닷넷데브의 일원들이 닷넷데브 외부 사람들은 물론 커뮤니티 내부의 다른 일원들과 커뮤니케이션을 할 때 존중받기를 기대합니다.
  • 단어나 어휘 선택에 신중을 기하세요. 닷넷데브의 모든 사람은 그 배경과 상관없이 모두 환영받고 있다고 느껴야 합니다. 커뮤니티의 동료 일원들에게 예의바르고, 존중하며, 공손하게 대해주세요. 성별, 성 정체성이나 성 표현, 성적 지향성, 장애, 신체적인 외모, 신체 크기, 인종, 종교와 관련된 공격적인 언급, 공공 장소에서의 성적 이미지 게시, 실제의 또는 은연 중의 폭력, 위협, 억압, 스토킹, 팔로잉, 괴롭힘의 성격이 있는 사진이나 레코딩, 얘기나 다른 행사의 흐름을 끊는 지속적인 개입, 부적절한 신체 접촉이나 원치 않는 성적인 관심 등은 용인되지 않습니다.
  • 효과적인 커뮤니케이션을 위해 노력해주세요. 우리가 모두 동일한 스킬 수준에서 동일한 언어를 말하지는 않습니다. 분명한 커뮤니케이션은 오해를 피하는데 도움이 될 수 있으며, 언어 해석이 각자 배경에 따라 다를 수 있음을 기억하는 것도 도움이 될 수 있습니다. 맥락을 이해하는 것도 중요합니다. 막연한 추측보다는 질문을 통해 분명한 의미를 확인하는 것이 더 낫습니다. 사회적으로, 기술적으로 의견의 불일치는 항상 있을 수 있지만, 커뮤니티 회원 여러분들께서는 불일치를 건설적으로 해결해 주실 것이라 기대합니다. 따라서 상호 공격, 트롤링, 개인적인 공격, 반복되는 논쟁, 악의적 신고 등은 피해 주시기 바랍니다.
3개의 좋아요