sml

SML { ❄ }

中文 EN

Chapter 8: Practical Application - Complete Project Configuration

Chapter 8: Practical Application: Complete Project Configuration

Put everything you have learned together: a deployment configuration that is close to reality, covering contracts, fragments include、 Environment variables, nested blocks, arrays.

8.1 File Disassembly

common.sml (public fragment+contract):

@contract Service loose {
    name:    str
    port:    int  default 8080 min 1 max 65535
    debug:   bool default false
    peers:   array[str] ?
}

@base {
    region: cn-north-1
    timeout: 30
}

app.sml (main configuration):

@version v1

include "common.sml"

# Top level application contract
@is Service
name: gateway
port: 9090
debug: true
peers: [ auth billing ]

# Fragment inheritance reuse
service auth { &base port: 7100 name: auth-svc }
service billing { &base port: 7200 name: billing-svc }

# Nested block+array
database: {
    url: $env.DATABASE_URL
    pool: { min: 2 max: 16 }
}
features: [ logging metrics tracing ]

After parsing, you will get a complete, structurally correct, and contract validated tree:

-The top layers name="gateway", port=9090, debug=true, and peers are arrays.

-service.auth automatically comes with region=cn-north-1, timeout=30 (from &base).

-database.url comes from environment variables, while database.pool is a nested block.

8.2 Progressive Enhancement: namespace isolation

When there are more modules, place each module in a separate file and use a namespace:

include "auth.sml" as modules.auth
include "billing.sml" as modules.billing

gateway {
    auth: modules.auth.config
    billing: modules.billing.config
}

In this way, any arbitrary definition of @contract/@name within auth.sml will not contaminate the scope of the main file.

8.3 Verification of Mental Models

When writing SML configuration, think in this order:

  1. Structure: Use blocks {} and arrays [] to layer the data.

  2. Reuse: Extract duplicate fields into @name fragments and reference them with &name.

  3. Split: If the file is too large, include; To isolate, use as ns.

  4. Constraint: Configuration is read to the program, using @contract+@is to lock the structure and eliminate errors during parsing.

  5. Decoupling: Use $env.VAR for sensitive/environment related values.

8.4 Next steps

-Do you want real-time trial and error? Write on the left and view the results on the right using online Playground.

-Check specific grammar/errors? Please refer to the appendix (/book/appendix).

-Do you want to read the complete design specifications? List of features of Site homepage.

Congratulations on reading this textbook! Now you can use SML to write production level configurations. → [Chapter 9: Advanced](/en/book/ch09 advanced)

Hands on practice

After reading this chapter, directly modify SML in the editor below and click “Run” to immediately see the parsing results or validation errors - having output is necessary for efficient learning.

✍ 动手练习 写一份接近真实的部署配置:@contract Service 定义在主文件,@is Service 写 name/port/debug;service auth 与 billing 都 &base 并覆盖 port/name;database 块含 url($env) 与 pool{min,max};features 数组。
💡 提示:这是一个接近真实的部署配置:契约 + 片段 + $env 一起用(契约定义放在主文件,避免跨文件引用)。
✍ 自测考题:第 8 章自测:实战项目 得分 0 / 3
Q1. 一个真实部署配置通常会组合哪些能力?
Q2. peers: [ auth billing ] 是什么类型?
Q3. 判断:database: { url: $env.DATABASE_URL } 把敏感信息留在源码外,是好的实践。