質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Go

    650questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

go言語 ginでjsonを返す時の可変長の時の対処方法について、

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,154

ShouYama

score 28

知りたいこと

jsonの値が変わる時にどうやってgin.H{}の中身を決めさせればいいかわからないので知りたい。

やりたいこと

指定した楽天のレシピからレシピのデータをもってきてjsonにしたい

コード

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "strings"

    "github.com/PuerkitoBio/goquery"
    "github.com/gin-gonic/gin"
)

type process struct {
    Image     string `json:"image"`
    Operation string `json:"operation"`
}

type material struct {
    Name     []string `json:"name"`
    Quantity []string `json:"quantity"`
}

//メインのjson
type mesi struct {
    Name        string    `json:"name"`
    Image       string    `json:"image"`
    MemberNum   string    `json:"membernum"`
    Time        string    `json:"time"`
    Fee         string    `json:"fee"`
    Explanation string    `json:"explanation"`
    Material    material  `json:"material"`
    Process     []process `json:"process"`
}

//料理名(タイトル)を返す。
func title(url string) string {
    var i string
    doc, _ := goquery.NewDocument(url)
    doc.Find("h1").Each(func(_ int, s *goquery.Selection) {
        i = s.Text()
    })
    return i
}

//何人前かを返す関数
func people(url string) string {
    var i string
    doc, _ := goquery.NewDocument(url)
    doc.Find("div > div > div > div > div > h3 > span > span").Each(func(_ int, s *goquery.Selection) {
        i = s.Text()
    })
    return i
}

//時間のをstringで返す
func time(url string) string {
    var i string
    doc, _ := goquery.NewDocument(url)
    doc.Find("time#indication_time_itemprop").Each(func(_ int, s *goquery.Selection) {
        i = s.Text()
    })
    return i
}
func fee(url string) string {
    var i string
    doc, _ := goquery.NewDocument(url)
    doc.Find("li.icnMoney").Each(func(_ int, s *goquery.Selection) {
        i = s.Text()
    })
    return i
}

//材料の量をstringの配列で返す
func materialQuantity(url string) []string {
    var quantity []string
    doc, _ := goquery.NewDocument(url)
    doc.Find("div > div > div > div > ul > li > p.amount").Each(func(_ int, s *goquery.Selection) {
        quantity = append(quantity, s.Text())
    })
    return quantity
}

//手順をstringの配列で返す
func procedure(url string) []string {
    var procedure []string
    doc, _ := goquery.NewDocument(url)
    doc.Find("li#step_box_li.stepBox > p.stepMemo").Each(func(_ int, s *goquery.Selection) {
        procedure = append(procedure, s.Text())
    })
    return procedure
}

//完成時の写真のurlをstringで返す。
func image(url string) string {
    var imgURL string
    doc, _ := goquery.NewDocument(url)
    doc.Find("div > div > span > img").Each(func(_ int, s *goquery.Selection) {
        url, _ := s.Attr("src")
        // fmt.Println(url)
        imgURL = url
    })
    return imgURL
}

//調理時のコツについてをstringで返す。
func kotu(url string) string {
    var kotu string
    doc, _ := goquery.NewDocument(url)
    doc.Find("div.howtoPointBox.last > p").Each(func(_ int, s *goquery.Selection) {
        kotu = s.Text()
    })
    return kotu
}

//材料の名前をstringの配列で返す
func mat(url string) []string {
    var materials []string
    doc, _ := goquery.NewDocument(url)
    doc.Find("div > div > div > div > ul > li > a#material_link.name").Each(func(_ int, s *goquery.Selection) {
        materials = append(materials, s.Text())
    })
    return materials
}

//説明文を返す。
func exp(url string) string {
    var i string
    doc, _ := goquery.NewDocument(url)
    doc.Find(" div >div > div > div > p.summary").Each(func(_ int, s *goquery.Selection) {
        i = s.Text()
    })
    return i
}

//どの工程が写真を持つかを返す
func haveImages(url string) []bool {
    var test []bool
    doc, _ := goquery.NewDocument(url)

    f := doc.Find("li#step_box_li.stepBox")
    f.Each(func(_ int, s *goquery.Selection) {
        t, _ := s.Html()
        if strings.Index(t, "img") != -1 {
            test = append(test, true)
        } else {
            test = append(test, false)
        }
    })
    return test
}

//作り方内の写真を得る
func getImages(url string) []string {
    var quantity []string
    doc, _ := goquery.NewDocument(url)
    doc.Find("img#step_image.processImage").Each(func(_ int, s *goquery.Selection) {
        t, _ := s.Attr("src")
        // fmt.Println(t)
        quantity = append(quantity, t)
    })
    return quantity
}

func makejson(num string) mesi {
    var recipe mesi
    var mats material
    var proc []process
    url := "http://recipe.rakuten.co.jp/recipe/"
    // sura := "/"
    url = url + num
    recipe.Name = title(url)
    recipe.Image = image(url)
    recipe.MemberNum = people(url)
    recipe.Explanation = exp(url)
    recipe.Time = time(url)
    recipe.Fee = fee(url)
    mats.Quantity = materialQuantity(url)
    mats.Name = mat(url)
    recipe.Material.Name = mats.Name
    recipe.Material.Quantity = mats.Quantity
    haveImage := haveImages(url)
    prImages := getImages(url)
    a := 0
    for i, operation := range procedure(url) {
        if haveImage[i] == true {
            proc = append(proc, process{
                Image:     prImages[a],
                Operation: operation,
            })
            a++
        } else {
            proc = append(proc, process{
                Image:     "",
                Operation: operation,
            })
        }
    }
    recipe.Process = make([]process, len(proc))
    copy(recipe.Process, proc)
    fmt.Println(recipe)
    return recipe
}

func main() {
    router := gin.Default()

    router.GET("/:num", func(c *gin.Context) {
        num := c.Param("num")
        t := makejson(num)
        bytes, _ := json.Marshal(t.Process)
        c.JSON(http.StatusOK, gin.H{"name": t.Name,
            "image":       t.Image,
            "membernum":   t.MemberNum,
            "time":        t.Time,
            "fee":         t.Fee,
            "explanation": t.Explanation,
            "material": gin.H{"name": t.Material.Name,
                "quantity": t.Material.Quantity},
            "prosess": ここ})
    })
    router.Run(":8080")
}

場所

上のコードの一番下にあるprosessってところをどうすればいいのか全く分からない

どうやって、配列のjsonをこういう宣言方法なのにどうやればいいのかわからないので、
わかる人是非教えてください、また、この書き方よりいいのがあるってのも知りたいです。
ginを初めて使ったので詳しくなくてだめなのでよろしくおねがいします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

gin.Hmap[string]interface{}型なので、そのままt.Processesを渡せば動作するはずです。しかし、そもそもc.JSONinterface{}型を受け取るので、そのままtを渡せば上手く動きませんか?

c.JSON(http.StatusOK, t)

interface{}型についてはこちらの空インターフェースの辺りからを参考にしてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Go

    650questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。