【cuetorials】入門 ~ cueでER図自動生成してみるまで❗️
こちらは「Applibot Advent Calendar 2022」5日目の記事になります.
はじめに
本記事では,cuelang入門~からcuelangを用いた自動生成周りについてまとめます.
まとめ
githubにサンプルコードと解説をまとめています
簡単なチュートリアルまとめたチートシート
概要
cueとは
cue言語は型付きでのスキーマ定義やデータバリデーションができる言語です.
jsonやyamlのデータ検証や自動生成元のデータをスキーマ付きで定義したりすることができます.
チュートリアル
導入
公式インストール方法にならい入れてみます.
macのためbrewで入れる.
brew install cue-lang/tap/cue
cueで変換してみる
cueはjsonやyamlに変換することができる.
pureなjsonを書く感じでまったく問題ないです.
一応下のような差分はあるが,cueの方が拡張されていて良い感じです.
- コメントアウトができる
- フィールド最後のコンマをつけても良い
- リスト最後のコンマをつけても良い
{
"name": "yuucu",
"age": 18,
// 所持しているアイテム
"items": [
"item1",
"item2",
],
}
$ cue export test.cue
コメントや最後のカンマが消えて正しいjsonの形式になっている.
{
"name": "yuucu",
"age": 18,
"items": [
"item1",
"item2"
]
}
cueでスキーマ定義をしてみる
以下の型が指定できる.
null bool string bytes number struct list
/ \
int float
構造体の定義は#
で書く (#user)
#user: {
"name": string,
"age": int,
// 所持しているアイテム
"items": [...string],
}
you: #user & {
"name": "yuucu",
"age": 18,
"items": [
"item1",
"item2",
],
}
$ cue export test.cue
{
"you": {
"name": "yuucu",
"age": 18,
"items": [
"item1",
"item2"
]
}
}
型検証
試しにage
に文字列を入れてみると error で知らせてくれる.
$ cue export test.cue
you.age: conflicting values int and "test string" (mismatched types int and string):
./test.cue:3:10
./test.cue:11:10
expressions
if文を使ってみる
#user: {
name: string,
age: int,
if age <= 50 {
isOld: false,
}
if age > 50 {
isOld: true,
}
}
you: #user & {
"name": "hoge",
"age": 10,
}
me: #user & {
"name": "hoge",
"age": 100,
}
age
によってisOldの値を分岐することができる
{
"you": {
"name": "hoge",
"isOld": false,
"age": 10
},
"me": {
"name": "hoge",
"isOld": true,
"age": 100
}
}
yaml merge
cue export
コマンドでjson/yamlのマージができる
cue export ./*.yaml
サンプルこちら
template 自動生成
templateに埋め込む機能を使ってみる
import "text/template"
tmplHello: """
Hi! {{.name}}.
"""
data: {
name: "yuucu"
}
out: template.Execute(tmplHello, data)
❯ cue export template.cue
{
"tmplHello": "Hi! {{.name}}.",
"data": {
"name": "yuucu"
},
"out": "Hi! yuucu."
}
全て出力されてしまうので絞りたい.
ヘルプをみると,-e
オプションで評価式を選択できるみたいでした.
❯ cue export fuga.cue -e out --out text
Hi! yuucu.
便利ですね!
go 構造体から.cue生成
cue get go
コマンドでできる
.cueから簡単にER図を作ってみる
詳細は↓クリック
data.cue
import "text/template"
#Tables: [...#Table]
#Table: {
name: string
columns: [...#Column]
}
// 雑にcolumnの定義
#Column: {
isPrimaryKey: bool | *false
name: string
type: "string" | "int"
}
data: #Tables
// puml用のtemplate
tmplPuml: """
@startuml
{{ range . }}
entity {{ .name }} {
{{ range .columns -}}
{{- if .isPrimaryKey -}}
{{ .type }} {{ .name }}
{{- end -}}
{{- end }}
---
{{- range .columns -}}
{{- if eq .isPrimaryKey false }}
{{ .type }} {{ .name }}
{{- end -}}
{{- end }}
}
{{ end }}
@enduml
"""
// mermaid用のtemplate
tmplMd: """
```mermaid
erDiagram
{{ range . -}}
{{ .name }} {
{{ range .columns -}}
{{ .type }} {{ .name }}
{{ end -}}
}
{{ end -}}
```
"""
// 実データ
data: [
#Table & {
name: "user"
columns: [
{
isPrimaryKey: true
name: "id"
type: "string"
},
{
name: "name"
type: "string"
},
{
name: "age"
type: "int"
},
]
},
#Table & {
name: "item"
columns: [
{
name: "id"
type: "string"
isPrimaryKey: true
},
{
name: "name"
type: "string"
},
{
name: "description"
type: "string"
},
]
},
]
// output
outPuml: template.Execute(tmplPuml, data)
outMd: template.Execute(tmplMd, data)
pumlへの出力
(go template力が弱く,インデントがたがたです...)
$ cue export ./data.cue -e outPuml --out text
@startuml
entity user {
string id
---
string name
int age
}
entity item {
string id
---
string name
string description
}
@enduml
>
で.pumlへ出して,みてみる
mermaidへの出力
$ cue export ./data.cue -e outMd --out text
```mermaid
erDiagram
user {
string id
string name
int age
}
item {
string id
string name
string description
}
```
>
で.mdへ出して,みてみる
まとめ(再掲)
githubにサンプルコードと解説をまとめています
簡単なチュートリアルまとめたチートシート
おわりに
便利ですね!
golangから.cueを扱うサンプルを試そうと思っていたのですが,
cueだけで自動生成実現できてしまったので,とてもびっくりです.
lspなりcueのエコシステムが発展することに期待です!
以上,「Applibot Advent Calendar 2022」 5日目の記事でした.
参考記事
Discussion