라라벨 - 아키텍처

김석재·2023년 5월 19일
0

PHP

목록 보기
4/6

아키텍처

2.1 MVC(Model, View, Controller)

라라벨은 기본적으로 MVC로 구성되어있다.

MVC 구조의 동작흐름

2.1.1 모델

모델(Model)은 사용자에게 보여줄 데이터를 의미. 데이터는 일반적으로 데이터베이스에 담겨있다.
라라벨 프레임워크 내부에서는 데이터베이스 테이블에 대해 하나의 클래스로 표현하고 각 컬럼또한 프로퍼티로 매핑되어있다. 모델에 있는 프로퍼티를 조작하고 데이터베이스와 관련된 메서드를 호출해서 데이터를 동기화하는 것으로 데이터베이스의 내용이 변하도록 할 수 있다.

라라벨에서는 엘로퀀트(Eloquent)라는 이름을 가진 ORM(Object Relational Mapping)을 사용한다면 SQL을 하드코드하지 않더라도 간단하게 데이터베이스 테이블에 접근하여 내용을 추가하거나 수정하고 조회할 수 있게 된다. 데이터 바인딩과 같은 부분은 라라벨이 알아서 처리한다.

$pdo = new PDO(...);

$sth = $pdo->prepare("SELECT * FROM users");

if($sth->execute()){
	users = [];
    
    while ($user = $sth->fetchObject()){
    	array_push($users, $user);
    }
}

라라벨을 사용하지 않고 PHP 내장 클래스중 하나인 PDO(PHP Data Object)레이어를 통해 쿼리를 준비한 다음, 실행하고 결과를 하나씩 가져와 배열에 넣는다. 쿼리를 준비하는 과정에는 SQL Injection 공격 방지를 위한 문자열 처리도 포함된다. PDO는 PHP에서 데이터베이스의 종류와 상관없이 동일한 인터페이스로 데이터베이스를 조작할 수 있는 레이어이며 모던 PHP에서 데이터베이스에 연결하기 위한 기본 개념중 하나다.
하지만 엘로퀀트 ORM을 사용하여 조회하면 아래와 같이 간결하게 처리될 수 있다.

$users = User::all();

User 모델에서 all()메서드를 마치 정적 메서드를 호출하는 것처럼 사용한 것을 볼 수 있는데, PHP의 언어 기능 중 하나인 매직 메서드에서 _callStatic()을 참조하면 확인할 수 있다.

2.1.2 뷰

뷰(View)는 사용자 인터페이스(UI)를 통해 HTTP요청을 다른 로직에 전달하거나, 컨트롤러에서 반환되어 사용자에게 응답한다. 응답으로 반환된 뷰는 렌더링되어서 사용자에게 보여지는데, 라라벨에서는 블레이드(Blade)라는 전용 템플릿을 사용한다.
블레이드 템플릿이 가지는 주요 기능 중 하나는 레이아웃 템플릿을 상속하거나 컴포넌트와 슬롯 등의 개념을 사용하여 마크업을 구성할 수 있다는 것이다.

2.1.3 컨트롤러

컨트롤러(Controller)에는 어플리케이션의 주요 로직이 담겨있다, 컨트롤러가 아닌 레이어드 아키텍처에 따라 서비스 레이어에 비즈니스 로직을 두는 경우가 더 많기는 하지만, 계층을 나누지 않는다면 컨트롤러에서 처리하게 된다. 컨트롤러는 사용자가 요청하면 라우터와 미들웨어를 거쳐 도달하게 되는데, 주로 모델을 생성하거나 갱신하게 되고 이후 뷰를 응답으로 반환하거나 다른 페이지로 리다이렉트, XML, JSON 등의 포맷으로 변환된 데이터를 반환하게 된다.

사용자가 HTTP요청을 하고 라우터를 통해 컨트롤러에 도달하는 과정

2.2 컨테이너

라라벨의 서비스 컨테이너는 IoC(Inversion of Control) 컨테이너, 어플레케이션 컨테이너 등 여러 이름을 가지고 있다. 컨테이너에 대해 알아보려면 먼저 의존성 주입에 대한 이해가 선행되어야 한다.

2.2.1 의존성 주입

의존성 주입은 생성자, 메서드, 세터에 파라미터를 통해 외부에서 구체 클래스 또는 인터페이스를 충족하는 객체를 넣는 것이다. 의존성이란 어떤 기능이 제대로 동작하기 위해서는 다른 기능에 의존하는 것이 필요함을 말하는데, 의존성을 외부에서 주입하지 않고 비즈니스 로직 내부에서 객체를 직접 생성하면 클래스간 결합도가 크게 증가하여 유연성이 떨어지게 된다.

2.2.2 서비스 컨테이너

라라벨의 서비스 컨테이너는 IoC 컨테이너로서 의존성을 외부에서 주입해서 해결해준다, IoC는 비즈니스 로직에서 의존성을 직접 제어하지 않고 컨테이너에 의해 외부로부터 주입하는 것으로 제어의 주체를 로직이 아닌 외부의 영역에서 하도록 만드는 것이다. 따라서 컨테이너는 객체의 생성 방법을 알고 있으며, 이를 대신해주고 필요한 곳에 주입해준다.
비즈니스 로직에서 어떠한 객체를 컨테이너에 요구하면 객체를 적절하게 생성해서 넘겨주게 되는데, 이를 의존성 해결이라 한다.
라라벨에서는 컨테이너를 통해 이를 명시적으로 객체를 생성해서 주입하지 않고도 서비스 컨테이너가 컨트롤러 등에서 타입힌트만 해주면 자동으로 의존성이 해결된다. 이를 오토 와이어링(Auto Wiring) 기능이라고 한다.

2.3 서비스 프로바이더

서비스 프로바이더는 라라벨 어플리케이션에 기능을 제공하기 위해 사용된다. 어플리케이션을 시작하기 위한 부트스트래핑이 진행되면서 발생하는 중요한 과정 중 하나는 서비스 프로바이더를 등록하고 부팅시키는 일이다.
기본적으로 라라벨 프레임워크 템플릿이 가지고 있는 서비스 프로바이더들음 app/Providers에 존재하며 AppSerciveProcider, RouteServiceProvider 등이 위치하고 있다.

2.3.1 부트스트래핑

서비스 프로바이더가 등록되고 부팅되는 부트스트래핑 과정

2.3.2. 지연된 서비스 프로바이더

지연된 서비스 프로바이더란 단순하게 서비스 프로바이더에 바인딩만을 등록하는 단순한 케이스의 경우, 의존성 해결을 위해 사용될 때까지 등록을 지연할 수 있는 프로바이더를 말한다. 어플리케이션을 부트스트래핑할 때 모든 요청에 대해 서비스 프로바이더를 로드해놓는 것이 아니라 해당 의존성 해결이 필요한 경우에만 서비스 프로바이더를 로드하고 등록하도록 할 수 있다.

2.4 파사드

라라벨의 파사드(Facades) 기능은 세션과 큐와 같은 라라벨의 기능들을 사용하기 위해 거쳐야하는 복잡한 절차를 간편하게 사용할 수 있도록 정적 메서드의 형태로 제공하는 라라벨의 기능 중 하나다.
파사드는 이름이 길고 기억하기 어려우며 사용하기에도 번거로운 구체 클래스 또는 인터페이스에 대해 정적 프록시 역할을 한다.

2.4.1 실시간 파사드

라라벨에는 실시간 파사드라는 기능이 있다. 실시간 파사드는 직접 파사드 클래스를 상속받아서 만들지 않더라도 그저 네임스페이스에 Facades만 붙이면 사용할 수 있는 기능을 제공한다.

use Facades\App\Contracts\Publisher;

class Podcast extends Model
{
	public function publish()
    {
    	Publisher::publish($this);
    }
}

이처럼 실시간 파사드를 사용하면 Illuminate\Support\Facades\Facade를 상속받아 파사드 클래스를 만들지 않더라도 간편하게 사용할 수 있다.

2.5 헬퍼함수

헬퍼함수는 특별한 것이 아니라 일반적인 함수이다. 단지, 라라벨에서 이 함수들의 이름을 지칭하는 것이 헬퍼이고, 귀찮은 작업들을 간단하게 할 수 있도록 도와준다. 라라벨에는 많은 헬퍼 함수가 존재하고 있다. 공식문서를 참고하면 확인이 가능하다.

2.6 Laravel Contracts

Contracts는 라라벨 프레임워크에서 단순히 인터페이스를 의미한다. 서비스 컨테이너의 바인딩에 따라 인터페이스를 컨테이너에 요청하면 구체 클래스를 던진다. 이러한 인터페이스를 타입힌트에 사용하여 의존성을 주입함으로써 사용하는 것이 가능하다.

0개의 댓글