1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

APIデータ取得を高速化する方法として、並列処理が有効です。Goの sync.WaitGroup を活用し、異なる2つのAPIからデータを並列で効率的に取得する方法を紹介します。具体的な例として、ユーザーデータと製品データの取得を行う架空のシナリオを設定し、直列処理と並列処理のコードを比較します。

改善前コード(直列処理)

package main

import (
    "errors"
    "fmt"
)

// UserData はユーザーのデータを表す架空の構造体です。
type UserData struct {
    ID   string
    Name string
}

// ProductData は製品のデータを表す架空の構造体です。
type ProductData struct {
    ID    string
    Title string
}

// FetchUserData は架空のユーザーデータ取得APIを模倣します。
func FetchUserData(userID string) (UserData, error) {
    // ここにAPI呼び出しのロジックを記述します(省略)。
    return UserData{ID: userID, Name: "John Doe"}, nil
}

// FetchProductData は架空の製品データ取得APIを模倣します。
func FetchProductData(productID string) (ProductData, error) {
    // ここにAPI呼び出しのロジックを記述します(省略)。
    return ProductData{ID: productID, Title: "Awesome Product"}, nil
}

// FetchData はユーザーと製品のデータを直列で取得します。
func FetchData(userID, productID string) (UserData, ProductData, error) {
    user, err := FetchUserData(userID)
    if err != nil {
        return UserData{}, ProductData{}, err
    }

    product, err := FetchProductData(productID)
    if err != nil {
        return UserData{}, ProductData{}, err
    }

    return user, product, nil
}

func main() {
    userID, productID := "user123", "product456"
    user, product, err := FetchData(userID, productID)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("User:", user)
    fmt.Println("Product:", product)
}

改善後コード(並列処理)

package main

import (
    "fmt"
    "golang.org/x/sync/errgroup"
)

// UserData と ProductData は前の例と同じです。

// FetchUserData と FetchProductData も前の例と同じです。

// FetchDataConcurrently はユーザーと製品のデータを並列で取得します。
func FetchDataConcurrently(userID, productID string) (UserData, ProductData, error) {
    var user UserData
    var product ProductData
    eg := new(errgroup.Group)

    // 最初のAPIを並列で呼び出し
    eg.Go(func() error {
        var err error
        user, err = FetchUserData(userID)
        return err
    })

    // 次のAPIを並列で呼び出し
    eg.Go(func() error {
        var err error
        product, err = FetchProductData(productID)
        return err
    })

    // すべてのゴルーチンが終了するのを待つ
    if err := eg.Wait(); err != nil {
        return UserData{}, ProductData{}, err
    }

    return user, product, nil
}

func main() {
    userID, productID := "user123", "product456"
    user, product, err := FetchDataConcurrently(userID, productID)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("User:", user)
    fmt.Println("Product:", product)
}

解説

errgroup.Groupを使って非同期に2つのAPI呼び出しを並列で行い、eg.Wait()を使ってすべてのゴルーチンが終了するのを待っています。エラーが発生した場合は、そのエラーをキャッチして適切に処理します。これにより、全体の実行時間を短縮し、より効率的なデータ取得します。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?