Phoenix for Rails 개발자: 실용적인 예 - 섹션 1

이것은 Phoenix를 소개하는 글입니다. Elixir의 웹 프레임워크입니다.이것은 완전한 지침이 아니다. 왜냐하면 이것은 많은 일을 깊이 연구해야 하는 큰 틀이 아니라 그들이 제공한 브래킷을 이용하여 두 틀 중의 일이 어떻게 완성되었는지 나란히 비교하고 고전적인 블로그 예시를 통해 그들의 가장 좋은 실천을 깊이 있게 이해하기 때문이다.
이것은 두 부분으로 구성된 블로그 문장으로 앞부분에서 우리는 두 프레임워크가 가장 비슷한 웹 층을 볼 것이다. 뒷부분에서 우리는 업무 층에 깊이 들어갈 것이다. 이것은 두 프레임워크의 차이점이다.
이 아이디어는 얼마나 비슷한지 보여주고 자신을 선전하기 위한 것이다.

소개


다양한 언어를 탐색한 후에 나는 루비를 연구하기 시작했다.문법은 나를 매혹시켰다. 표현력이 이렇게 강하고 영어처럼 읽을 수 있으며 이렇게 많은 도구가 있어서 나는 그 어느 때보다 효율적으로 일을 할 수 있었다.문자열 보조 함수나 서투른 순환을 사용하여 그룹을 조작할 필요가 없습니다. 이 모든 것을 상자를 열고 사용할 수 있습니다. 해결 방안을 작성하는 데 전념하십시오.한참이 지나서 레일스를 찾았는데 루비의 철학에 딱 맞는 것 같았어요.나는 다른 공구보다 더 효율적이라고 생각한다. 게다가 그것은 배터리도 포함한다.네가 모든 일을 할 수 있는 라이브러리에 대해 몇 시간의 설정이나 연구가 없다.
그때부터 나는 각종 언어로 다른 웹 개발 프레임워크를 많이 시도했지만, 그 중 어느 것도 자유롭지 못했다.많은 사람들이 Rails가 한 일을 복제하려고 해도 언어 때문이든 결정 때문이든 항상 복제품 같다.

봉황


Phoenix에 들어가면 이것은 Elixir 위에 세워진 웹 프레임워크이고 Elixir는 기능성 언어로 루비와 유사한 문법을 가지고 Erlang 가상 컴퓨터에서 실행된다.이 프레임워크는 Rails의 많은 특성을 계승한다. MVC 구조, ORM, 템플릿 엔진과 루트 층 등 도구를 포함하는 고집적인 파일 구조이다.그러나 다른 사본이 되려고 시도한 적이 없다. 반대로 시간의 흐름에 따라 의견이 다르고 기능 모델과 언어에 더 적합한 결정을 내렸기 때문에 생산력이나 개발자의 행복감을 희생하지 않았다.
시간의 흐름에 따라 이것은 독립된 웹 프레임워크를 초래했지만 우리가 모두 좋아하는 Rails의 특수한 스타일을 가지고 있다.그러나 한 가지 차이점은 Elixir는 Erlang에서 구축된 것이기 때문에 Erlang은 대규모 확장 가능한 응용 프로그램을 구축하는 데 목적을 두고 있기 때문에 모든 Phoenix로 구축된 응용 프로그램은 이 특권을 계승했다.이것은 코드를 작성할 수 있다는 것을 의미하며, 일단 메이저리그에 들어가면 응용 프로그램이 어떻게 실행될지 걱정할 필요가 없다.이것은 많은 Rails 응용 프로그램이 해결하려고 노력하는 문제이자 Jose Valim이 먼저 Elixir를 개발한 주요 원인이다.
하지만 충분히 가르쳤으니 실제 행동을 봅시다!

파일 구조


만약 어떻게 문서를 조직할 것인지를 고려하지 않는다면, 어떤 고집스러운 틀도 완전하지 않다.우선 폴더 보기의 내용을 봅시다.이것은 두 가지 프레임워크가 있는 응용 프로그램을 만들 때 얻은 결과입니다.

Phoenix의 구조는 패키지(Elixir는gems에 해당)의 구조를 계승하고 모든 사용자 정의 코드는 lib/ 폴더에 있습니다.그 안에서 두 프레임워크의 주요 차이점을 발견할 수 있다. 피닉스는 웹 표시층과 업무 논리를 분리한다.위 그림에서는 Railsblog/ 디렉토리와 매우 유사하게 보이는 비즈니스 논리를 구축하는 기본 모듈과 blog_web 폴더가 있습니다.비록 약간의 미세한 차이가 존재하지만, 우리는 다음과 같은 몇 절에서 그것들을 깊이 있게 연구할 것이다.

비계


내가 언급한 바와 같이, 이 두 프레임워크는 응용 프로그램의 다른 부분을 구축하는 데 사용되는 명령을 제공한다.이 예제에서는 전체 리소스 (뷰 및 라우팅 포함) 의 출력을 비교하지만 우선 사용되는 명령을 비교합니다.
bin/rails generate scaffold Article title:string text:text
mix phx.gen.html Articles Article articles title:string text:text
그것들은 보기에 비슷하고 미세한 차이가 있다. 본 예에서 피닉스는 더욱 상세한 방식을 채택하여 그 중에서 창설될 상하문 모듈, 모델 모듈의 명칭(모델에 해당)과 복수 형식을 지정하여 테이블 이름으로 사용하도록 요구했다.

노선


각 웹 요청은 라우팅에서 올바른 프로세싱으로 시작됩니다. 먼저 간단한 라우팅을 살펴보고 Rails가 어떻게 처리되는지 살펴보겠습니다.
Rails.application.routes.draw do
  resources :articles
end
Rails의 라우팅은 매우 간단합니다. 라우팅을 이해하면 최종 사용자가 사용할 수 있는 어떤 포트만 지정하여 GEM(또는 더 정확히 말하면 엔진과 플러그인)이 라우팅을 마운트하고 Deviseapp/ 방법과 같은 검증을 할 수 있습니다.요청의 조작은 컨트롤러에서 이루어지며, 때로는 값이 어디에서 왔는지, 누가 요청을 해석했는지, 누가 요청을 거절했는지 알기 어렵다.봉황성은 이에 대해 다른 견해를 가지고 있다.
defmodule BlogWeb.Router do
  use BlogWeb, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", BlogWeb do
    pipe_through :browser

    resources "/articles", ArticleController
    get "/", PageController, :index
  end


  scope "/api", BlogWeb do
    pipe_through :api
  end
end
이것은 더 많은 코드가 필요하지만, 단지 더 많은 책임이 있기 때문이다.여기서 보신 authenticate 호출은 중간부품과 비교할 수 있는 것들을 정의합니다. 정의된 순서에 따라 직렬적으로 실행됩니다.그것들은 plug 함수와 조합되어 있기 때문에 역할 영역에서 호출(Rails와 유사)하여 해석, 인증, 권한 수여 등 조작과 조작을 실행하기 전에 실행해야 할 다른 조작을 수행할 수 있다.
이것은 대부분의 상황에서 컨트롤러를 권한 수여 사용자와 요청을 거부하는 논리적 결합을 허용하여 pipeline 호출을 대체하고 많은 상황에서 컨트롤러 간의 복잡한 계승 수요를 줄일 수 있다.

컨트롤러


다음 단계는 실제 처리입니다. 두 공장 모두 MVC 모델을 따르기 때문에 이것은 컨트롤러에서 완성된 것입니다.이런 것들에 대해 저는 동작만 보여주고 차이를 빠르게 훑어보기로 했습니다. 함수 프로그래밍에서 Phoenix가 무엇을 하는지 설명해야 할 부분이 많습니다. 이것은 본고의 주제가 아닙니다.만약 당신이 Elixir의 문법에 흥미를 느낀다면, Elixir Getting Started Guide 은 좋은 시작이다.솔직히 말씀드리지만, 컨트롤러를 소개합니다.
class ArticlesController < ApplicationController
  before_action :set_article, only: [:show,
                                     :edit,
                                     :update,
                                     :destroy]

  def index
    @articles = Article.all
  end

 def new
    @article = Article.new
  end

 def create
    @article = Article.new(article_params)

    respond_to do |format|
      if @article.save
        format.html { redirect_to @article }
        format.json { render :show, status: :created,
                             location: @article }
      else
        format.html { render :new }
        format.json { render json: @article.errors,
                             status: :unprocessable_entity }
      end
    end
  end
end
defmodule BlogWeb.ArticleController do
  use BlogWeb, :controller

  alias Blog.Articles
  alias Blog.Articles.Article

  def index(conn, _params) do
    articles = Articles.list_articles()
    render(conn, "index.html", articles: articles)
  end

  def new(conn, _params) do
    changeset = Articles.change_article(%Article{})
    render(conn, "new.html", changeset: changeset)
  end

  def create(conn, %{"article" => article_params}) do
    case Articles.create_article(article_params) do
      {:ok, article} ->
        conn
        |> put_flash(:info, "Article created successfully.")
        |> redirect(to: Routes.article_path(conn, :show, article))

      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end
end
이곳의 주요 차이점은 단지 프로그래밍 모델일 뿐이다.Elixir는 기능적이기 때문에 요청(또는 연결)과 파라미터는 조작의 파라미터로 수신되고, 루비는 대상을 대상으로 국부 상태와 접근기 함수를 통해 같은 데이터를 제공합니다.그러나 문법은 매우 비슷해서 피닉스 코드 단편의 내용을 쉽게 파악할 수 있다고 생각합니다.
또 다른 작은 차이점은 피닉스에 사용되는 생성기는 HTML에만 응답하는 컨트롤러를 구축하고 Rails는 JSON과 HTML의 보기를 동시에 보여준다는 것이다.물론 JSON 자원을 생성하는 또 다른 생성기가 있지만, 이 컨트롤러는 다른 파이프에서 실행될 것입니다. (루트 부분으로 돌아가면 before_action 파이프를 볼 수 있습니다.

보조 객체 및 뷰


마지막으로 가장 중요하지 않은 것은 우리가 웹 층에 데이터를 어떻게 표시하는지가 아니다.파일 구조에서 자세히 보지 않으면 Phoenix 프로젝트 구조에는 :apiviews/ 두 개의 디렉터리가 있습니다.그것들 사이의 차이가 무엇인지 알고 싶을 수도 있습니다. 템플릿은 삽입식 코드가 있는 텍스트 파일 (eb가 있는 것처럼 eex) 을 사용해서 요청에 응답합니다.다른 한편, 보기는 보조 대상과 유사하지만 뚜렷한 차이가 있다. 기본적으로 전체적인 것이 아니다.
우리 하나의 예로 그것들 사이의 차이를 봅시다.우리는 문장에 읽는 시간을 표시하고 싶다.우리는 데이터베이스에서 이 값을 추적하지 않기 때문에, 이것은 단지 프레젠테이션을 위한 것이기 때문에, 당신은 보통 그것을 다음과 같이 조수 위에 두기를 원합니다.
module ArticlesHelper
  WORDS_PER_MINUTE = 200

  def read_time(article)
    words_count = article.text.split.size
    read_time_in_minutes = words_count / WORDS_PER_MINUTE.to_f
    #{read_time_in_minutes.ceil} minutes"
  end
end
긴장을 풀자. 이제 우리는 그것templates/을 상향 조정하여 사용하기만 하면 완성된다.그리 빠르지 않다. 내가 본 문제는 그것이 모든 보기에 포함되어 있다는 것이다.물론 이런 이름이 이렇게 구체적인 작은 응용 프로그램에는 문제가 없지만, 그것이 증가하기 시작하면, 당신의 조수의 이름인 show.html.erbformat_title 은 귀찮아지기 시작할 것이다.Phoenix의 도움말(또는 프레임의 보기)과 매우 비슷합니다.
defmodule BlogWeb.ArticleView do
  use BlogWeb, :view

  alias Blog.Articles.Article

  @words_per_minute 200

  defp read_time(%Article{text: text}) do
    words_count =
      text
      |> String.split(" ")
      |> Enum.count()
    read_time_in_minutes = Float.ceil(words_count / @words_per_minute)
    "#{trunc(read_time_in_minutes)} minutes"
  end
end
그러나 내가 전에 말한 바와 같이 그들의 작용역은 일부 시범자이다. 예를 들어 이 보기는 문장 템플릿에서만 호출할 수 있는 함수를 가지고 있다.이것은 당신이 원하는 모든 이름을 사용할 수 있도록 허락합니다. 당신이 전 세계를 오염시키지 않을 것이라는 것을 알고 있습니다.만약 여러 개의 템플릿을 뛰어넘어 통용 함수를 사용하고 싶다면?간단하게 말하면 이 함수로 다른 모듈을 만들고 필요한 보기에 포함시킨다.

따라가다


이것은 웹 층의 차이에 대한 간략한 소개를 끝냈다.다음으로 본고의 두 번째 부분은 데이터와 업무층이다.

좋은 웹페이지 즐겨찾기