창고 개발이 더 쉬울 거예요.

처음에는 창고 개발자만 있었다.우리는 PHP 또는 Ruby On Rails으로 백엔드에서 모든 것을 실현한 후에 jQuery으로 전방에서 조금 운행하여 우리는 완성하였다.
하지만 시대가 변했다.현대 인터넷 응용 프로그램은 풍부한 사용자 인터페이스를 필요로 하는데 이런 인터페이스는 더 이상 백엔드에서 나타나지 않는다.
따라서 우리는 "single-page application" 모델로 전환하여 그 전단이 사용자 인터페이스를 완전히 관리한다.
백엔드는 관리역 모델과 업무 논리만 필요하기 때문에 간소화되었다.
문제는 우리가 지금 전단과 후단을 연결해야 한다는 것이다. 이것이 바로 일이 복잡해지는 곳이다.
우리는 웹 API(REST, GraphQL 등)를 구축했는데 이 API는 코드의 크기를 현저히 증가시켰고 역 모델의 복제를 초래했다.
실제로 이것은 두 개의 응용 프로그램을 구축하는 것과 같다.
그래서 우리는 개발자의 수를 배로 늘릴 것이다. 전체적인 복잡도는 이렇다. 우리는 그들을 전단과 후단 개발자로 나눈다.
만약 당신이 반창고 개발자라면, 당신은 반쪽의 일을 할 수 있을 뿐, 당신은 다른 반쪽의 일을 담당하는 사람과 교류하는 데 많은 시간을 들였다.
만약 당신이 창고 개발자라면, 당신은 진정한 영웅입니다.당신은 더욱 효율적이고 만족스러운 방식으로 처음부터 끝까지 하나의 특성을 실현할 수 있습니다.
프런트엔드와 백엔드 개발자를 구분하면 생산력을 떨어뜨리고 모든 즐거움을 파괴할 수 있다.
하지만 솔직히 오늘 완전한 창고 개발자는 way too difficult이다.
이상적인 상황에서 우리는 모두 처음처럼 꽉 차야 한다.그러나 이를 위해서는 창고를 크게 간소화해야 한다.

단순화된 스택


가장 간단한 프로젝트의 경우, 예를 들어 Parse, Firebase 또는 Amplify을 사용할 수 있다.그러나 업무 논리가 CRUD 조작을 초과할 때는 그다지 좋지 않다.
8년 전에 Meteor이라는 것이 출현했다.그 주요 사상은 전단과 후단 간의 통신을 간소화하는 것이었는데, 당시에는 상당히 혁명적이었다.불행하게도 이 프로젝트는 노화가 잘 되지 않아 오늘날의 환경에 더 이상 적합하지 않다.
최근 두 가지 프로젝트가 센세이션을 일으켰다. RedwoodJSBlitz.js이다.둘 다 프런트엔드와 백엔드 간의 통신을 간소화하기 위한 것이지만 방법은 다르다.
RedwoodJS는 GraphQL API의 실현을 간소화하고 ReactPrisma을 견해 있는 프레임워크에 통합시켰다.
번개전.js도 React와Prisma를 사용하는 프레임워크이지만 Next.js을 바탕으로 구축된 것으로 웹 API에 대한 수요를 없애려고 노력한다.
이 프로젝트들은 전체 창고 응용 프로그램의 개발을 간소화하는 올바른 방향으로 나아가고 있다. 나는 그들이 성공하기를 바란다.
하지만 이 분야에서의 저의 시도를 소개해 드리겠습니다. Liaison이라는 프로젝트에 1년 반 동안 종사했습니다.

연락


나는 가능한 한 창고를 평평하게 하기 위해 미혹자와 연락을 맺었다.
일반적인 스택은 데이터 액세스, 백엔드 모델, API 서버, API 클라이언트, 프런트엔드 모델과 사용자 인터페이스로 구성된 6층으로 구성됩니다.
연락을 통해 창고는 전면과 후면을 통일하는 단일 논리층으로 간주될 수 있다.

문제는 모든 층이 더 많은 코드 분산, 지식 중복, 샘플과 우연한 복잡성을 초래할 수 있다는 것이다.
연락은 단일 논리층에서 응용 프로그램을 조립하여 이 문제를 극복할 수 있도록 합니다.

계층 간 상속


연락으로 백엔드에서 프런트엔드를 계승할 수 있습니다.그것의 작업 원리는 일반적인 클래스 계승과 유사하지만, 서로 다른 환경에서 층을 뛰어넘어 운행한다.
물리적으로 말하자면, 우리는 여전히 독립된 전단과 백엔드를 가지고 있지만, 논리적으로 말하자면, 우리는 전체 응용 프로그램을 통일시키는 단일한 층을 가지고 있다.
백엔드 클래스에서 계승된 백엔드 클래스에서 방법을 호출할 때 실행은 방법이 실현되는 곳-백엔드 또는 백엔드에서 발생한다. 이것은 방법의 사용자와 무관하다.실행 환경이 추상화되다.
온전한 "Hello, World!" 창고와 연락의 관계를 봅시다.
먼저 백엔드:
import {Component, attribute, method, expose} from '@liaison/component';
import {ComponentHTTPServer} from '@liaison/component-http-server';

class Greeter extends Component {
  @expose({set: true}) @attribute() name = 'World';

  @expose({call: true}) @method() async hello() {
    return `Hello, ${this.name}!`;
  }
}

const server = new ComponentHTTPServer(Greeter, {port: 3210});

server.start();
프런트엔드:
import {ComponentHTTPClient} from '@liaison/component-http-client';

const client = new ComponentHTTPClient('http://localhost:3210');

const Greeter = await client.getComponent();

const greeter = new Greeter({name: 'Steve'});

console.log(await greeter.hello());

Note: This article focuses on the architectural aspect of the stack, so don't worry if you don't fully understand the code.


전단을 실행할 때 hello() 방법이 호출되며, 후단에서 이 방법을 실행하는 것은 세부적인 것으로 볼 수 있다.
프런트엔드의 Greeter 클래스는 일반 JavaScript 클래스와 유사하며 확장할 수 있습니다.예를 들어, hello() 메서드를 다음과 같이 덮어쓸 수 있습니다.
class ExtendedGreeter extends Greeter {
  async hello() {
    return (await super.hello()).toUpperCase();
  }
}
현재 hello() 방법을 호출할 때 실행은 전단과 후단에서 동시에 발생합니다.그러나 실행이 발생하는 위치는 세부 사항으로 볼 수 있다.
개발자의 입장에서 볼 때 전단과 후단은 하나의 일로 모든 것을 더욱 쉽게 한다.

데이터 지구층


대부분의 응용 프로그램은 데이터를 저장해야 하기 때문에 여기서도 크게 간소화할 수 있다.
이 생각은 결코 신선하지 않다. ORM으로 데이터베이스를 추상화할 수 있는데 이것이 바로 연락소가 따르는 방법이다.
간단히 말하면, Storable() mixin은 당신의 데이터에 지속성을 가져다 줍니다.예를 들어, 다음 과정을 학습합니다.
import {Component} from '@liaison/component';
import {Storable, primaryIdentifier, attribute} from '@liaison/storable';

class Movie extends Storable(Component) {
  @primaryIdentifier() id;
  @attribute() title;
}
Movie을 만들고 저장하려면 다음과 같이 하십시오.
const movie = new Movie({title: 'Inception');
await movie.save();
기존 Movie을 읽어들이려면 다음과 같이 하십시오.
const movie = await Movie.get({id: 'abc123'});
마찬가지로 여기에는 active record pattern을 사용하는 어떤 ORM과도 유사한 새로운 내용이 없다.
연락처와 달리 ORM은 백엔드에만 국한되지 않습니다.계층 간 상속 메커니즘을 통해 전면에서도 ORM을 사용할 수 있습니다.
따라서 개념적으로 말하자면 우리는 여전히 단일한 논리층을 가지고 전단, 백엔드와 데이터베이스를 결합시킨다.

사용자 인터페이스


일반적인 응용에서 사용자 인터페이스와 도메인 모델은 완전히 분리된다.몇 년 전, 사용자 인터페이스는 기본적으로 명령식 코드로 구성되어 있기 때문에 이렇게 하는 좋은 이유가 있었다.그러나 현재 우리는 사용자 인터페이스와 도메인 모델을 결합시킬 수 있는 기능적인 UI 라이브러리(예를 들어 React with hooks)를 가지고 있다.
연락은 루트와 보기를 모델로 하는 방법을 허용합니다.
다음은 노선을 정의하는 방법의 예입니다.
import {Component} from '@liaison/component';
import {Routable, route} from '@liaison/routable';

class Movie extends Routable(Component) {
  @route('/movies') static List() {
    // Display all the movies...
  }

  @route('/movies/:id') static Item({id}) {
    // Display a specific movie...
  }
}
보시다시피 라우팅은 모델 메서드와 연관된 URL일 뿐입니다.
다음은 뷰를 구현하는 방법입니다.
import {Component, attribute} from '@liaison/component';
import React from 'react';
import {view} from '@liaison/react-integration';

class Movie extends Component {
  @attribute() title;
  @attribute() year;
  @attribute() country;

  @view() Home() {
    return (
      <div>
        <this.Heading />
        <this.Details />
      </div>
    );
  }

  @view() Heading() {
    return (
      <h3>
        {this.title} ({this.year})
      </h3>
    );
  }

  @view() Details() {
    return <div>Country: {this.country}</div>;
  }
}
보기는 모델 속성을 바탕으로 일부 내용을 되돌리는 방법일 뿐, 사용자 인터페이스 요소를 되돌리는 것은 근본적으로 문제가 아니다.
보기가 모델에 연결되어 있기 때문에 상태 관리자를 사용하지 않아도 될 수도 있습니다. 예를 들어 Redux 또는 MobX입니다. @view() 장식기는 속성 값이 변경될 때 자동으로 보기를 다시 렌더링합니다.
따라서 우리는 사용자 인터페이스를 역모델에 봉하여 걱정해야 할 문제를 줄였다.

결론


나는 완전한 창고 개발을 더욱 쉽게 실현하려면 편평화 창고가 매우 중요하다고 굳게 믿는다.
연락은 두 개의 물리 층 (프런트엔드와 백엔드) 에서 하나의 논리 층에 집중된 완전한 창고 응용 프로그램을 구축할 수 있도록 합니다.
가능한 한 적은 층을 써서 프로젝트를 시작하는 것은 비교적 쉽지만, 이것은 당신이 반드시 이런 방식으로 모든 프로젝트를 구축해야 한다는 것을 의미하지는 않는다.
일부 항목에 대해 응용 프로그램을 더 많은 층으로 분해하는 것은 좋은 생각일 수 있다.예를 들어 데이터 접근을 백엔드 모델과 분리하거나 사용자 인터페이스를 백엔드 모델과 분리하는 것이 유용할 수 있다.
걱정 마.계층 간 상속 메커니즘을 사용하면 단일 논리 계층을 유지하면서 물리 계층을 추가할 수 있습니다.
만약 대상을 대상으로 프로그래밍하는 것이 당신의 취미가 아니라면, 당신은 연락하는 것을 좋아하지 않을 것이다.하지만 OOP가 엉망진창인 조합 모델을 제공했다고 해서 거절하지 마세요.JavaScript 클래스는 기능적으로 정의할 수 있습니다(예: mixins). 따라서 매우 강한 조합성을 가지고 있습니다.
Liaison documentation을 보고 물건을 만들기 시작하고 당신의 생각을 보세요.
본고는 최초로 let me know에 발표되었다.

좋은 웹페이지 즐겨찾기