You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言消费API时如何将JSON转换为Go类型定义并存储数据

How to Convert API JSON Response to Go Structs (Focus on Dynamic Time Series Field)

Hey there! Let's work through converting that Alpha Vantage API response into Go structs, especially focusing on the tricky Time Series (1min) field with dynamic timestamp keys. Here's a step-by-step solution that's type-safe and easy to work with for your future calculations.

Step 1: Define Matching Go Structs

First, we'll create structs that mirror the JSON structure. The key insight here is using a map[string]TimeEntry for the time series—since each timestamp is a unique string key, this map will perfectly capture those dynamic entries.

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
)

// MetaData maps the "Meta Data" object from the JSON response
type MetaData struct {
	Information   string `json:"1. Information"`
	Symbol        string `json:"2. Symbol"`
	LastRefreshed string `json:"3. Last Refreshed"`
	Interval      string `json:"4. Interval"`
	OutputSize    string `json:"5. Output Size"`
	TimeZone      string `json:"6. Time Zone"`
}

// TimeEntry represents the price/volume data for a single timestamp
type TimeEntry struct {
	Open   string `json:"1. open"`
	High   string `json:"2. high"`
	Low    string `json:"3. low"`
	Close  string `json:"4. close"`
	Volume string `json:"5. volume"`
}

// APIResponse is the top-level struct wrapping the entire JSON response
type APIResponse struct {
	MetaData       MetaData             `json:"Meta Data"`
	TimeSeries1Min map[string]TimeEntry `json:"Time Series (1min)"`
}

Note: The json:"..." tags must exactly match the keys in the JSON, including spaces and number prefixes like "1. open". If you prefer numeric types (like float64 for prices), you can change the fields in TimeEntry to float64/int64—just make sure to handle any parsing errors if the JSON has invalid numbers.

Step 2: Parse the JSON Response with encoding/json

Now update your main function to unmarshal the JSON into our structs. Don't forget to close the response body to avoid resource leaks!

func main() {
	response, err := http.Get("https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=1min&apikey=demo")
	if err != nil {
		fmt.Printf("HTTP request failed: %s\n", err)
		return
	}
	defer response.Body.Close() // Critical to free resources

	data, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Printf("Failed to read response body: %s\n", err)
		return
	}

	// Unmarshal JSON into our APIResponse struct
	var apiResp APIResponse
	if err := json.Unmarshal(data, &apiResp); err != nil {
		fmt.Printf("JSON unmarshal failed: %s\n", err)
		return
	}

	// Example: Access and use the parsed data
	fmt.Println("Symbol:", apiResp.MetaData.Symbol)
	fmt.Println("Last Refreshed:", apiResp.MetaData.LastRefreshed)

	// Loop through time series entries for calculations
	for timestamp, entry := range apiResp.TimeSeries1Min {
		// Convert close price to float64 for calculations
		closePrice, err := strconv.ParseFloat(entry.Close, 64)
		if err != nil {
			fmt.Printf("Failed to parse close price for %s: %s\n", timestamp, err)
			continue
		}
		fmt.Printf("Timestamp: %s | Close Price: %.4f\n", timestamp, closePrice)
	}
}

Alternative: Using jsonq (If You Prefer)

Since you were already using jsonq, here's how to extract the time series data with it—though structs are better for type safety long-term:

// Add this import at the top: "github.com/jmoiron/jsonq"

func main() {
	// ... (same HTTP request and read body code as before)

	jq := jsonq.NewQuery(data)
	// Extract the time series object
	timeSeries, err := jq.Object("Time Series (1min)")
	if err != nil {
		fmt.Printf("Failed to get time series: %s\n", err)
		return
	}

	// Iterate through each timestamp entry
	for timestamp, entry := range timeSeries {
		entryMap := entry.(map[string]interface{})
		closePrice, _ := jq.String(entryMap, "4. close")
		fmt.Printf("%s: Close = %s\n", timestamp, closePrice)
	}
}

Key Takeaways

  • Dynamic fields: Use map[string]YourStruct when JSON has keys that change (like timestamps here).
  • Type safety: Structs are always preferred over raw map[string]interface{} because they enforce data types and make code more maintainable.
  • Error handling: Always check for errors during HTTP requests, reading bodies, and unmarshaling—this saves you from silent failures later.

内容的提问来源于stack exchange,提问作者Philip Mutua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:49:23