The Apicalypse query language client for Go
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.travis.yml
LICENSE
README.md
apicalypse.go
apicalypse_test.go
filter.go
filter_test.go
option.go
option_test.go

README.md

Apicalypse

GoDoc Build Status Coverage Status Go Report Card

Create custom Apicalypse compliant queries with the apicalypse Go package. With the apicalypse package, you can create queries with any of the supported filters including: Fields, Exclude, Where, Limit, Offset, Sort, and Search. The package will be kept up to date with Apicalypse - if more filters are introduced, they will be supported here as well. To see the complete list of filters and their respective syntax please visit the Apicalypse syntax page here.

If you would like to lend a hand with the package, please feel free to submit a pull request. Any and all contributions are welcome and appreciated!

Installation

If you do not have Go installed yet, you can find installation instructions here.

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

go get github.com/Henry-Sarabia/apicalypse

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

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

Usage

Creating A New Request

Creating a new request is as straightforward as you would imagine - simply use the NewRequest() function as follows.

req, err := apicalypse.NewRequest("GET", "https://myapi.com/actors")

You may provide any method and URL to the function but be aware that the Apicalypse specifications recommend a simple GET request for the majority of cases. POST and PUT requests may be used under certain circumstances.

For more information, please visit the Apicalypse implementation page here.

Functional Options

The apicalypse package uses functional options to apply the different query filters to a request. More specifically, functional options are first-order functions that are passed to the NewRequest() function. It's much simpler than it sounds and the package makes it easy!

Let's walk through a few different functional option examples to demonstrate their ease of use.

To specify what fields to return from an API query, pass Fields() to the NewRequest() function.

req, err := apicalypse.NewRequest("GET", "https://myapi.com/actors", Fields("name", "movies", "age"))

With that, our new request is configured to only fetch the "name", "movies", and "age" fields from our friends at the totally, absolutely real myapi.com.

To specify the limit of results we want returned from an API query, pass Limit() to the NewRequest() function.

req, err := apicalypse.NewRequest("GET", "https://myapi.com/actors", Limit(15))

It's no more difficult than that - we're ready to fetch up to 15 results!

Although this next example may initially look more complicated, it is only a matter of adhering to the proper Apicalypse syntax. Again, that can be found here.

To specify a filter for our results from an API query, pass Where() to the NewRequest() function.

req, err := apicalypse.NewRequest("GET", "https://myapi.com/actors", Where("age > 50 & movies != null"))

Our new request is now configured to filter the results so only the results which have an age above 50 and a non-null movies field are returned.

The remaining functional options are no more complicated than the examples presented here. Moreover, they are further described in the documentation.

Functional Option Composition

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

First, the NewRequest() function is variadic which means you can pass in any number of functional options.

req, err := apicalypse.NewRequest(
	"GET",
	"https://myapi.com/actors",
	Fields("name", "movies", "age"),
	Where("age > 50 & movies != null"),
	Limit(15),
	)

Leveraging the variadic nature of the NewRequest() function, we have quickly and simply created a request with several different filters automatically applied to it.

This request is now configured to return results with the fields "name", "movies", and "age". In addition, the results will be filtered so only results with age above 50 and a non-null movies field are returned. Finally, only up to 15 results will be returned.

Second, the apicalypse package provides a ComposeOptions() function which takes any number of functional options and composes them into a single, custom made, ready-to-use functional option.

myOpt := apicalypse.ComposeOptions(
	Fields("name", "movies", "age"),
        Where("age > 50 & movies != null"),
        Limit(15),
	)

This call to ComposeOptions() creates a single functional option that performs the same filters we've been using up until now. The major difference is that now we only need to provide this new single functional option to any new requests that require those specific filters.

req, err := apicalypse.NewRequest("GET", "https://myapi.com/actors", myOpt)

Of course, you can still pass in additional functional options if need be.

For example, now that we've gathered our 15 results, perhaps we want the next 15. It's as simple as passing in one more functional option.

req, err := apicalypse.NewRequest("GET", "https://myapi.com/actors", myOpt, Offset(15))

Our new request is ready to return the next 15 results!

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 queries.

Examples

The repository contains a few examples that demonstrate how one could use the apicalypse package. The examples can be found in their respective test files or be read conveniently on the GoDoc reference found here.

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

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.

I'll review pull requests as they come in and merge them if everything checks out.

Again, any contribution is greatly appreciated!

Special Thanks

  • The IGDB team who developed Apicalypse with an accompanying Node client
  • The helpful community over on the IGDB Discord server
  • The insightful Dave Cheney for his article on functional options