콘텐츠로 이동

Go-프론트엔드 브리지

Wails는 Go와 JavaScript 간에 직접적인 인메모리 브리지를 제공하여, HTTP 오버헤드, 프로세스 경계, 또는 직렬화 병목 현상 없이 원활한 통신을 가능하게 합니다.

Diagram

핵심 통찰: HTTP 없음, IPC 없음, 프로세스 경계 없음. 오직 직접적인 함수 호출타입 안전성만 있습니다.

애플리케이션이 시작될 때, Wails는 당신의 서비스를 스캔합니다:

type GreetService struct {
prefix string
}
func (g *GreetService) Greet(name string) string {
return g.prefix + name + "!"
}
func (g *GreetService) Add(a, b int) int {
return a + b
}
// Register service
app := application.New(application.Options{
Services: []application.Service{
application.NewService(&GreetService{prefix: "Hello, "}),
},
})

Wails가 수행하는 작업:

  1. 내보낸 메서드에 대해 구조체 스캔
  2. 타입 정보 추출 (매개변수, 반환 타입)
  3. 메서드 이름을 함수에 매핑하는 레지스트리 빌드
  4. 완전한 타입 정의가 포함된 TypeScript 바인딩 생성

Wails는 TypeScript 바인딩을 자동으로 생성합니다:

frontend/bindings/GreetService.ts
export function Greet(name: string): Promise<string>
export function Add(a: number, b: number): Promise<number>

타입 매핑:

Go 타입TypeScript 타입
stringstring
int, int32, int64number
float32, float64number
boolboolean
[]TT[]
map[string]TRecord<string, T>
structinterface
time.TimeDate
error예외 (던져짐)

개발자가 JavaScript에서 Go 메서드를 호출합니다:

import { Greet, Add } from './bindings/GreetService'
// Call Go from JavaScript
const greeting = await Greet("World")
console.log(greeting) // "Hello, World!"
const sum = await Add(5, 3)
console.log(sum) // 8

발생하는 일:

  1. 바인딩 함수 호출 - Greet("World")
  2. 메시지 생성 - { service: "GreetService", method: "Greet", args: ["World"] }
  3. 브리지로 전송 - WebView의 JavaScript 브리지를 통해
  4. Promise 반환 - 응답을 대기

브리지는 메시지를 받고 처리합니다:

Diagram

보안: 등록된 서비스와 내보낸 메서드만 호출할 수 있습니다.

Go 메서드가 실행됩니다:

func (g *GreetService) Greet(name string) string {
// This runs in Go
return g.prefix + name + "!"
}

실행 컨텍스트:

  • 고루틴에서 실행 (비차단)
  • 모든 Go 기능에 접근 가능 (파일 시스템, 네트워크, 데이터베이스)
  • 다른 Go 코드를 자유롭게 호출 가능
  • 결과 또는 오류 반환

결과가 JavaScript로 다시 전송됩니다:

// Promise resolves with result
const greeting = await Greet("World")
// greeting = "Hello, World!"

오류 처리:

func (g *GreetService) Divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
try {
const result = await Divide(10, 0)
} catch (error) {
console.error("Go error:", error) // "division by zero"
}

일반적인 호출 오버헤드: <1ms

Frontend Call → Bridge → Go Execution → Bridge → Frontend Response
↓ ↓ ↓ ↓ ↓
&lt;0.1ms &lt;0.1ms [varies] &lt;0.1ms &lt;0.1ms

대안과 비교:

  • HTTP/REST: 5-50ms (네트워크 스택, 직렬화)
  • IPC: 1-10ms (프로세스 경계, 마샬링)
  • Wails 브리지: <1ms (인메모리, 직접 호출)

호출당 오버헤드: ~1KB (메시지 버퍼)

제로 복사 최적화: 큰 데이터 (>1MB)는 가능한 경우 공유 메모리를 사용합니다.

호출은 동시적입니다:

  • 각 호출은 자체 고루틴에서 실행됩니다
  • 여러 호출이 동시에 실행될 수 있습니다
  • 호출 간 차단 없음
// These run concurrently
const [result1, result2, result3] = await Promise.all([
SlowOperation1(),
SlowOperation2(),
SlowOperation3(),
])
// Go
func Example(
s string,
i int,
f float64,
b bool,
) (string, int, float64, bool) {
return s, i, f, b
}
// TypeScript (auto-generated)
function Example(
s: string,
i: number,
f: number,
b: boolean,
): Promise<[string, number, number, boolean]>
// Go
func Sum(numbers []int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
// TypeScript
function Sum(numbers: number[]): Promise<number>
// Usage
const total = await Sum([1, 2, 3, 4, 5]) // 15
// Go
func GetConfig() map[string]interface{} {
return map[string]interface{}{
"theme": "dark",
"fontSize": 14,
"enabled": true,
}
}
// TypeScript
function GetConfig(): Promise<Record<string, any>>
// Usage
const config = await GetConfig()
console.log(config.theme) // "dark"
// Go
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func GetUser(id int) (*User, error) {
return &User{
ID: id,
Name: "Alice",---
**브리지 관련 질문이 있으신가요?** [Discord](https://discord.gg/JDdSxwjhGf)에서 질문하거나 [바인딩 예제](https://github.com/wailsapp/wails/tree/master/v3/examples/binding)를 확인하세요.