Magicode logo
Magicode
0
5 min read

V言語で超簡単なAPIサーバを作る。 part.3

カサレリア。katzenです。

前回、 V言語で超簡単なAPIサーバを作る。 part.2でjsonを返すAPIサーバを作りました。

その際、vweb.json()を使用することで、自分でjsonエンコードをしなくても、jsonを返せる。

context-typeも自動で設定される。と書きました。

vwebとしては、htmltextjsonなどは用意されていますが、標準ですべてのcontext-typeをカバーしたメソッドを持っているわけではありません。

では、例えば画像を返したい場合などうすればいいでしょうか。

vwebのコード を読んでみましょう。

context_typeというプロパティがあることがわかります。

ほかにも

jsonメソッドの中で使われている、send_response_to_clientやヘッダーを追加出来ると思われる add_headerset_content_typeと目的そのままのものがあることがわかりました。

きっとこれを使えば、context_typeを指定できるはずです。

あとは何でレスポンスを返すかですね。 見てみると、context_typeを使用して値を返すメソッドがありますね。

これで行けそうです。組み込んでみましょう。

fn (mut app App)svg() vweb.Result {
  svg := '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="width:128;height:128" xml:space="preserve"><path d="m378,0H195L48,147v279c0,47,39,86,86,86h245c47,0,86-39,86-86V86c-1-47-39-86-87-86zm54,426c0,30-24,54-54,54H134c-30,0-54-24-54-54V161h84c25,0,45-20,45-45V32h170c30,0,54,24,54,54v340zM180,297h-1c-11-1-14-5-14-10,0-6,4-10,12-10,6,0,11,2,16,4h-1c5,0,9-4,9-9l1-1c-5-3-15-6-26-6-20,0-32,11-32,28,0,16,10,25,29,27l1-3c11,1,14,5,14,10,0,6-5,11-15,11-7,0-12-2-20-6v-2c-5,0-9,4-9,9l0,2c6,4,16,8,29,8,24,0,36-12,36-29s-10-25-29-28zm101-37c-5,0-8,2-10,8l-17,55-18-55c-2-5-5-8-10-8-6,0-10,4-10,9l24,72c3,8,7,12,13,12s10-3,13-12l24-72c0-5-4-9-10-9zm83,41h-19c-5,0-8,3-8,8s3,8,8,8l6,10c-2,6-8,9-15,9-8,0-13-4-15-10-1-3-1-8-1-20s0-16,1-20c2-6,7-10,15-10,6,0,10,2,14,7,3,4,5,5,9,5,5,0,9-4,9-9l0-1c-5-8-15-14-30-14-16,0-29,7-34,22-2,6-3,12-3,25s1,19,3,25c5,15,17,22,34,22,16,0,29-8,33-23,2-5,2-13,2-21l-1-3c0-5-3-8-8-8z" fill="#4B4B4B"/></svg>'
  app.set_content_type('image/svg+xml')
  return app.ok(svg)
}

起動してhttp://localhost:8080/svgへアクセスするとsvgが表示されるはずです。

簡単ですね。

今回のソース

import vweb

struct App{
  vweb.Context
}

struct Result {
  status bool
  message string
}

fn main() {
  vweb.run(&App{}, 8080)
}


fn (mut app App) index() vweb.Result {
  result := Result{
    status: true
    message: "タイヤが空を飛ぶな" 
  }
  return app.json(result)
}

['/say/:message']
fn (mut app App) say(message string) vweb.Result {
  result := Result{
    status: true
    message: "おかしいですよ!" + message + "さん"
  }
  return app.json(result)
}

fn (mut app App)svg() vweb.Result {
  svg := '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="width:128;height:128" xml:space="preserve"><path d="m378,0H195L48,147v279c0,47,39,86,86,86h245c47,0,86-39,86-86V86c-1-47-39-86-87-86zm54,426c0,30-24,54-54,54H134c-30,0-54-24-54-54V161h84c25,0,45-20,45-45V32h170c30,0,54,24,54,54v340zM180,297h-1c-11-1-14-5-14-10,0-6,4-10,12-10,6,0,11,2,16,4h-1c5,0,9-4,9-9l1-1c-5-3-15-6-26-6-20,0-32,11-32,28,0,16,10,25,29,27l1-3c11,1,14,5,14,10,0,6-5,11-15,11-7,0-12-2-20-6v-2c-5,0-9,4-9,9l0,2c6,4,16,8,29,8,24,0,36-12,36-29s-10-25-29-28zm101-37c-5,0-8,2-10,8l-17,55-18-55c-2-5-5-8-10-8-6,0-10,4-10,9l24,72c3,8,7,12,13,12s10-3,13-12l24-72c0-5-4-9-10-9zm83,41h-19c-5,0-8,3-8,8s3,8,8,8l6,10c-2,6-8,9-15,9-8,0-13-4-15-10-1-3-1-8-1-20s0-16,1-20c2-6,7-10,15-10,6,0,10,2,14,7,3,4,5,5,9,5,5,0,9-4,9-9l0-1c-5-8-15-14-30-14-16,0-29,7-34,22-2,6-3,12-3,25s1,19,3,25c5,15,17,22,34,22,16,0,29-8,33-23,2-5,2-13,2-21l-1-3c0-5-3-8-8-8z" fill="#4B4B4B"/></svg>'
  app.set_content_type('image/svg+xml')
  return app.ok(svg)
}

今回context_typeを指定して値を返すことが出来ました。 画像データを直接文字列としてコードに書いていますが、 os.read_file()あたりを使ってファイルから読み込み、表示するのがほとんどでしょう。

要望とかあればまた紹介したいと思います。

Discussion

コメントにはログインが必要です。