Go client for the Internet Game Database API

Overview

IGDB

GoDoc Build Status Coverage Status Go Report Card Mentioned in Awesome Go

Communicate with the Internet Game Database API quickly and easily with the igdb package. With the igdb client, you can retrieve extensive information on any number of video games, characters, companies, media, artwork and much more. Every IGDB API endpoint is supported!

If you would like to help the Go igdb project, please submit a pull request - it's always greatly appreciated.

Installation

If you do not have Go installed yet, you can find installation instructions here. Please note that the package requires Go version 1.13 or later for module support.

To pull the most recent version of igdb, use go get.

go get github.com/Henry-Sarabia/igdb

Then import the package into your project as you normally would.

import "github.com/Henry-Sarabia/igdb"

Now you're ready to Go.

Usage

Creating A Client

Before using the igdb package, you need to have an IGDB API key. If you do not have a key yet, you can sign up here.

Create a client with your Client-ID and App Access Token to start communicating with the IGDB API.

client, err := igdb.NewClient("YOUR_CLIENT_ID", "YOUR_APP_ACCESS_TOKEN", nil)

If you need to use a preconfigured HTTP client, simply pass its address to the NewClient function.

client, err := igdb.NewClient("YOUR_CLIENT_ID", "YOUR_APP_ACCESS_TOKEN", &custom)

Services

The client contains a distinct service for working with each of the IGDB API endpoints. Each service has a set of service functions that make specific API calls to their respective endpoint.

To start communicating with the IGDB, choose a service and call its service function. Take the Games service for example.

To search for a Game, use the Search service function.

games, err := client.Games.Search("zelda")

To retrieve several Games by their IGDB ID, use the List service function.

games, err := client.Games.List([]int{7346, 1721, 2777})

The rest of the service functions work much the same way; they are concise and behave as you would expect. The documentation contains several examples on how to use each service function.

Service functions by themselves allow you to retrieve a considerable amount of information from the IGDB but sometimes you need more control over the results being returned. For this reason, the igdb package provides a set of flexible functional options for customizing a service function's API query.

Functional Options

The igdb package uses what are called functional options to apply different query parameters to service function's API call. Functional options themselves are merely first order functions that are passed to a service function.

Let's walk through a few different functional option examples.

To set the limit of the amount of results returned from an API query, pass SetLimit to the service function.

games, err := client.Games.Search("megaman", SetLimit(15))

As you can see, you simply need to pass the functional option as an argument to the service function.

To offset the results returned from an API call, pass SetOffset to the service function.

games, err := client.Games.Search("megaman", SetOffset(15))

SetOffset is used to iterate through a large set of results that cannot be retrieved in a single API call. In this case, the first 15 results are ignored so we effectively iterated through to the next set of results by 15.

To set the order of the results returned from an API call, pass SetOrder much in the same way as the previous examples.

games, err := client.Games.Search("megaman", SetOrder("hypes", igdb.OrderDescending))

SetOrder is used to specify in what order you want the results to be retrieved in and by what criteria. Here, SetOrder will retrieve the results with the highest hypes first.

The remaining functional options are not unlike the examples we covered and are further described in the documentation.

Functional Option Composition

More often than not, you will need to set more than one option for an API query. Fortunately, this functionality is supported through variadic functions and functional option composition.

First, service functions are variadic so you can pass in any number of functional options.

chars, err := client.Characters.Search(
    "mario",
    SetFields("id", "name", "games"),
    SetFilter("gender", "1"),
    SetLimit(5), 
    )

This API call will search the Characters endpoint using the query "mario", filter out any character that does not have a gender code of 1 (which in this case represents male), retrieve the id, name, and games fields, and return only up to 5 of these results.

Second, the igdb package provides a ComposeOptions function which takes any number of functional options as its parameters, composes them into a single functional option, and returns that composed functional option.

hypeOpt := igdb.ComposeOptions(
    igdb.SetLimit(5),
    igdb.SetFields("name"),
	igdb.SetOrder("hypes", igdb.OrderDescending),
)

This call to ComposeOptions creates a single functional option that will allow you to retrieve the names of the top 5 most popular games when passed to the appropriate service function.

Functional option composition allows you to create custom functional options that can be reused in different API calls.

Taking the previous example, this can be done in the following way.

PS4, err := c.Games.Index(
		popularOpt,
		igdb.SetFilter("platforms", igdb.OpEquals, "48"),    // filter out games not on PS4
    )
    
XBOX, err := c.Games.Index(
		popularOpt, 
		igdb.SetFilter("platforms", igdb.OpEquals, "49"),    // filter out games not on XB1
    )

This example has two service function calls that each utilize the previously composed functional option in the same way but for different platforms. The first function retrieves the top 5 most popular PS4 games while the second function retrieves the top 5 most popular XB1 games.

Functional option composition reduces duplicate code and helps keep your code DRY. You can even compose newly composed functional options for even more finely grained control over similar API calls.

Examples

The repository contains several example mini-applications that demonstrate how one might use the igdb package.

If you have used the igdb package for a project and would like to have it featured here as a reference for new users, please submit an issue and I'll be sure to add it.

Contributions

If you would like to contribute to this project, please adhere to the following guidelines.

  • Submit an issue describing the problem.
  • Fork the repo and add your contribution.
  • Add appropriate tests.
  • Run go fmt, go vet, and golint.
  • Prefer idiomatic Go over non-idiomatic code.
  • Follow the basic Go conventions found here.
  • If in doubt, try to match your code to the current codebase.
  • Create a pull request with a description of your changes.

Again, contributions are greatly appreciated!

Special Thanks

  • You for your interest
  • John for the IGDB Gopher
  • Peter for the "Thank You" Gopher
  • Dave Cheney for his article on functional options
  • The DiscordGo and Go Spotify projects for inspiring me to create my own open source package for others to enjoy
  • The Awesome Go project for so many references to admire
  • The awesome people in the IGDB community who are always open to questions
Comments
  • Why is  client.Games.List ids required now?

    Why is client.Games.List ids required now?

    Hello.

    IDs where nil and my script worked fine. Now the ids are required. Why? My script is getting game realeases between two dates where ids are not existing. Is there other way i could achieve that after update.

    question 
    opened by kaidoj 5
  • adding new Game Category enum values

    adding new Game Category enum values

    Updated Game Category enums to support the values:

    • mod, 5
    • episode, 6
    • season, 7

    IGDB documentation: https://api-docs.igdb.com/#game-enums

    I regenerated the go generate files via stringer and looks like more recent versions output an additional func than originally.

    opened by Lavos 4
  • Private endpoints may need additional authorization

    Private endpoints may need additional authorization

    There may be an additional required header to be sent in each request for pro and enterprise tier users. If this is the case, the auth token must be supported in the NewClient function or another function entirely.

    question 
    opened by Henry-Sarabia 3
  • Offset and Limit options have erroneous hard limits

    Offset and Limit options have erroneous hard limits

    SetLimit and SetOffset returns error if number higher than 5000 is provided.

    There is no limit for offset for IGDB v4 API. image

    Limit also changed to 500 (not 5000 as in the code). image

    According to: https://api-docs.igdb.com/#pagination

    bug 
    opened by ksewo 2
  • ServerError struct does not have Temporary method

    ServerError struct does not have Temporary method

    When attempting to assert that the errors.Cause(err) of a returned error from a service is Temporary for the new ratelimiting requirements:

    type temporary interface {
            Temporary() bool
    }
    
    func IsTemporary(err error) bool {
            te, ok := errors.Cause(err).(temporary)
            fmt.Printf("IS TEMPORARY %#v %t\n", errors.Cause(err), ok)
            return ok && te.Temporary()
    }
    

    This prints:

    IS TEMPORARY igdb.ServerError{Status:429, Msg:"too many requests", Temp:true} false
    

    errors.Cause() returns a plain igdb.ServerError, not *igdb.ServerError, and a plain igdb.ServerError does not implement temporary. Only *igdb.ServerError has the required Temporary method: https://github.com/Henry-Sarabia/igdb/blob/dcac61d5a6ea36eb1265af5e5f0cfdf479adf14f/error.go#L72

    Is there any reason we can't define this method on igdb.ServerError as that will cover both plain struct and pointer?

    bug 
    opened by Lavos 2
  • Updating to V4 of IGDB

    Updating to V4 of IGDB

    https://api-docs.igdb.com/#upgrading-to-v4-from-v3

    Updating Authentication

    • Changed from user-key to client-id
    • Added AppAccessToken as required param
    • Added x-user-agent as a way of identifying client code that may need updates.

    Methods

    • Changed from GET to POST

    Endpoints

    | Endpoint | Change | |-------------------|-----------| |achievement_icons |Removed | |achievements |Removed | |feed_follows |Removed | |feeds |Removed | |follows |Removed | |list_entries |Removed | |lists |Removed | |page_backgrounds |Removed | |page_logos |Removed | |page_websites |Removed | |pages |Removed | |product_families |Renamed to platform_families | |pulse_images |Removed | |pulse_groups |Removed | |pulse_sources |Removed | |pulse_urls |Removed | |pulses |Removed | |rates |Removed | |review_videos |Removed | |reviews |Removed | |status |Removed | |time_to_beats |Removed | |titles |Removed |

    Changed Fields

    |Object |Endpoint |Field |Change| |-----------|-----------|---------------|------| |Game |games |popularity |Removed| |Game |games |pulse_count |Removed| |Game |games |time_to_beat |Removed| |Platform |platforms |product_family |Renamed to platform_family| |Search |search |popularity |Removed|

    opened by dustyjewett 2
  • Expanding fields breaks JSON decoding

    Expanding fields breaks JSON decoding

    The IGDB API now supports field expansion. Field expansion allows a user to denote subfields to retrieve in addition to the regular fields of a request. Because Go is a statically typed language, when additional subfields are sent back in the JSON object, the object will no longer match the defined struct and the JSON decoder will return an error.

    Here are three options for dealing with this problem.

    1. Ignore the issue and simply let the package return a JSON decoder error when expansion is used.
    2. Take a half-measure and fail early. Document the lack of expansion support and check for any expanded fields before sending the request. If an expanded field is found, return an error explaining the lack of expansion support.
    3. Take a half-measure and return an untyped object. Add an extra function for each endpoint that allows expansion but will return an untyped map of the JSON object instead of a proper populated Go struct type.
    bug 
    opened by Henry-Sarabia 2
  • Implement private IGDB endpoints

    Implement private IGDB endpoints

    IGDB has a set of private endpoints meant for pro tier users. Three of these endpoints are listed under the regular list of endpoints so they are already implemented, but there still remains a dozen unimplemented endpoints.

    enhancement 
    opened by Henry-Sarabia 2
  • Improve test coverage

    Improve test coverage

    Test coverage has dropped to 92% after the most recent pull request. It would be prudent to reevaluate the current suite of tests to raise the overall test coverage.

    enhancement 
    opened by Henry-Sarabia 2
  • Update igdbURL to v3 endpoint

    Update igdbURL to v3 endpoint

    Wanted to start playing around with the IGDB API, but it turns out that new API keys are only valid for this new API v3 endpoint.

    I'm not sure if more changes are probably in order for v3 compatibility: https://api-docs.igdb.com/#migration-to-v3

    opened by mark-ignacio 2
  • ts.Client undefined

    ts.Client undefined

    Hey! I'm new to using this project and looks like it will be perfect if I can get it running.

    When getting the project from github (and when trying to build my own project) I'm getting the following error:

    ../../../../../github.com/Henry-Sarabia/igdb/testing.go:44: ts.Client undefined (type *httptest.Server has no field or method Client)

    I pulled the latest about an hour ago.

    Thanks!

    opened by tmwoods 2
  • Unable to Filter by Name for GameVideos

    Unable to Filter by Name for GameVideos

    There might be an issue filtering by non-id fields for GameVideos.Index().

    Querying the IGDB API https://api.igdb.com/v4/game_videos directly with the following body yields a single item.

    Body:

    fields name,video_id;
    where id = 48965;
    limit 500;
    offset 0;
    

    Response:

    [
        {
            "id": 48965,
            "name": "Announcement Trailer",
            "video_id": "61-OMrOxyso"
        }
    ]
    

    Querying by name instead of id yields a response with multiple items:

    Body:

    fields name,video_id;
    where name = ("Announcement Trailer");
    limit 500;
    offset 0;
    

    When using this library, filtering by ID works but not by Name. Works:

    options := igdb.ComposeOptions(
    		igdb.SetLimit(500),
    		igdb.SetOffset(0),
    		igdb.SetFields("name, video_id"),
    		igdb.SetFilter("id", igdb.OpContainsAtLeast, "48965"),
    	)
    
    videos, err := IGDB.GameVideos.Index(options)
    

    Doesn't Work:

    options := igdb.ComposeOptions(
    		igdb.SetLimit(limit),
    		igdb.SetOffset(offset),
    		igdb.SetFields("name, video_id"),
    		igdb.SetFilter("name", igdb.OpContainsAtLeast, "Announcement Trailer"),
    	)
    
    videos, err := IGDB.GameVideos.Index(options)
    

    We get the following error with the above request: Error: cannot get index of GameVideos: cannot make POST request: igdb server error: status: 400 message: bad request: check query parameters

    Any thoughts on how we can fix this?

    Thanks!

    opened by HammerMeetNail 0
  • Missing Field for Website Struct

    Missing Field for Website Struct

    Hello,

    website.go has the following struct:

    type Website struct {
    	ID       int             `json:"id"`
    	Category WebsiteCategory `json:"category"`
    	Trusted  bool            `json:"trusted"`
    	URL      string          `json:"url"`
    }
    

    Game is also available via the API, but not exposed in this struct. See https://api-docs.igdb.com/#website

    Can we add it? Should look like:

    type Website struct {
    	ID       int             `json:"id"`
    	Category WebsiteCategory `json:"category"`
            Game     int             `json:"game"`
    	Trusted  bool            `json:"trusted"`
    	URL      string          `json:"url"`
    }
    

    Let me know if you want me to open a PR with this change. Thanks!

    opened by HammerMeetNail 0
Releases(v2.0.0-alpha.4)
  • v2.0.0-alpha.4(Dec 15, 2020)

  • v2.0.0-alpha.3(Oct 20, 2020)

  • v2.0.0-alpha.2(Sep 30, 2020)

  • v2.0.0-alpha.1(Sep 30, 2020)

    Issues for major v2.0.0-alpha.1

    This major update addresses the IGDB API's upgrade to v4. For information on specific changes, visit the IGDB documentation.

    • Improvements

      • Client
        • Replaced GET requests with POST requests (#91, #74 - thanks to @dustyjewett)
        • Updated root API URL (#73 - thanks to @dustyjewett)
      • Authentication
        • Updated required credentials (#76 - thanks to @dustyjewett)
      • Endpoints
        • Removed unsupported endpoints (#77, #78 - thanks to @dustyjewett)
      • Types
        • Updated fields for Game, Platform, and SearchResult structs (#79 - thanks to @dustyjewett)
        • Added missing GameCategory enumerated types (#70 - thanks to @Lavos)
      • Errors
        • Implemented Temporary behavior for temporary server errors (#75)
    • Bugfixes

      • Removed obsolete Client fields (#81)
      • Removed DeepEqual error checking (#83)
      • Removed TestDummy endpoint (#89)
        • This is an undocumented change in the IGDB documentation
      • Fixed error checking in ReleaseDateService tests (#82)

    Thanks again to our contributors.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.3(Feb 4, 2020)

    Issues for patch v1.0.3

    • Improvements
      • Documentation
        • Added support for Go modules (#64)
        • Removed outdated tier-system information (#60)
        • Updated required Go version in README (#66)
    • Bugfixes
      • Redefined type Screenshot to match the API definition (#58 - Thanks @gotomgo!)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Nov 13, 2019)

  • v1.0.1(Mar 5, 2019)

  • v1.0.0(Mar 6, 2019)

    Issues for major v1.0.0

    • Features
      • Filters
        • All filters are now Apicalypse-compliant (#4)
        • Functional Options have been simplified (#8)
        • Exclude option is now available for excluding specific fields from a request (#31)
      • Endpoints
        • All new public endpoints are fully supported (#4, #35, #51)
        • Private endpoints are included, but authentication is not implemented yet (#13, #36)
      • Search
        • Search now supports the following: Characters, Collections Games, People, Platforms, and Themes (#10)
        • Search has its own endpoint but can still be used on the previously mentioned endpoints (#10)
      • Service Functions
        • List has been split into two functions: List and Index (#4, #47)
    • Improvements
      • Errors
        • Errors are now wrapped with more context (#12)
        • Redundant errors have been removed (#12)
        • Server errors have been updated (#16)
      • Documentation
        • All exported constants now have proper documentation (#43, #46)
        • Examples have been updated (#6, #42)
        • README has been updated to reflect all changes (#21)
      • Testing
        • Test coverage has improved (#11, #16, #18, #20, #23, #38)
        • Remove some repeated reflection that was slowing down tests (#27)
      • Internal
        • Several out-of-scope functions were factored out into their own packages (#7, #15)
    Source code(tar.gz)
    Source code(zip)
Owner
Henry Sarabia
I have a BS in CS at CSU Fresno. I am a full stack developer who primarily works in Go and TypeScript with React and Vue to develop web applications and APIs.
Henry Sarabia
Client-go - Clusterpedia-client supports the use of native client-go mode to call the clusterpedia API

clusterpedia-client supports the use of native client-go mode to call the cluste

clusterpedia.io 9 Dec 5, 2022
Pokemon Unite scoreboard HUD and extra tools running over captured game feeds using the OpenCV video processing API and Client/Server architecture.

unite Pokemon Unite scoreboard HUD and extra tools running over captured game feeds using the OpenCV video processing API. Client (OBS Live) Server Ar

pidgy 6 Dec 5, 2022
twitter clone front-end for Internet Engineering course - fall 99 built by go+echo

twitter backend build twitter-like back-end for internet engeering course - fall 99 with go+echo+gorm team mates Roozbeh Sharifnasab + Parsa Fadaee +

Roozbeh Sharifnasab 15 Nov 9, 2022
A Go client implementing a client-side distributed consumer group client for Amazon Kinesis.

Kinesumer is a Go client implementing a client-side distributed consumer group client for Amazon Kinesis.

당근마켓 70 Jan 5, 2023
Nutanix-client-go - Go client for the Nutanix Prism V3 API

nutanix-client-go This repository contains portions of the Nutanix API client code in nutanix/terraform-provider-nutanix. It has been extracted to red

Marvin Beckers 0 Jan 6, 2022
Client-Server Expression Evaluator with Persistent Database Support (Redis & SQL)

Client-Server-Expression-Evaluator Client-Server Expression Evaluator with Persistent Database Support (Redis & SQL). Client-Server Expression Evaluat

Muhammad Soomro 0 Jan 4, 2022
Go client for the YNAB API. Unofficial. It covers 100% of the resources made available by the YNAB API.

YNAB API Go Library This is an UNOFFICIAL Go client for the YNAB API. It covers 100% of the resources made available by the YNAB API. Installation go

Bruno Souza 55 Oct 6, 2022
An API client for the Notion API implemented in Golang

An API client for the Notion API implemented in Golang

Anatoly Nosov 354 Dec 30, 2022
A Wrapper Client for Google Spreadsheet API (Sheets API)

Senmai A Wrapper Client for Google Spreadsheet API (Sheets API) PREPARATION Service Account and Key File Create a service account on Google Cloud Plat

ytnobody / satoshi azuma 0 Nov 5, 2021
yet another movie database api

##Yet Another Movie Database API API Method URL Pattern Action GET /v1/healthcheck Show application health and version information GET /v1/movies Show

Pedro Gabriel 0 Nov 30, 2021
Simple-Weather-API - Simple weather api app created using golang and Open Weather API key

Simple Weather API Simple weather api app created using golang and Open Weather

Siva Prakash 3 Feb 6, 2022
Client for the cloud-iso-client

cloud-iso-client Client for the cloud-iso-client. Register an API token Before using this client library, you need to register an API token under your

Virtomize 0 Dec 6, 2021
Go-http-client: An enhanced http client for Golang

go-http-client An enhanced http client for Golang Documentation on go.dev ?? This package provides you a http client package for your http requests. Y

Furkan Bozdag 52 Jan 7, 2023
Aoe4-client - Client library for aoe4 leaderboards etc

AOE4 Client Overview This is a go client used to query AOE4 data from either the

Mark Smith 0 Jan 18, 2022
Balabola-go-client - GO client for Yandex balabola service

Balabola GO Client GO client for Yandex balabola service Yandex warning The neur

Konovalov Maxim 0 Jan 29, 2022
Client-server-golang-sqs - Client Server with SQS and golang

Client Server with SQS and golang Multi-threaded client-server demo with Go What

null 0 Feb 14, 2022
CLI timed quiz game parsed from CSV file in GOLANG

Quiz-Game-GO CLI timed quiz game parsed from csv file in GOLANG Read the quiz provided via a CSV file and will then give the quiz to a user keeping tr

Adarsh Singh 0 Dec 3, 2021
A simple command line -based snake game built with go and termbox

snake-task Snake Game A simple command line -based snake game built with go and termbox library. This is a test task for a Golang positon. It took me

Kingsley Ugwudinso 1 Jan 16, 2022
Go Client Library for Amazon Product Advertising API

go-amazon-product-advertising-api Go Client Library for Amazon Product Advertising API How to Use go get -u github.com/ngs/go-amazon-product-advertisi

Atsushi NAGASE 54 Sep 27, 2022