# github-rest


A package providing a more flexible interface to accessing the [GitHub API](https://developer.github.com/v3/).
Endpoints are created using the `GHEndpoint` constructor and are executed with
the `queryGitHub` function in the `GitHubT` monad.
## Quickstart
This quickstart will demonstrate querying endpoints in a hypothetical public
GitHub repo `alice/my-project`.
```haskell
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
import Data.Text (Text)
import GitHub.REST
import Network.HTTP.Types (StdMethod(..))
default (Text)
main = do
let state = GitHubSettings
{ token = Nothing
-- ^ An authentication token to use, if any.
, userAgent = "alice/my-project"
-- ^ GitHub requires this to be set to a User Agent specific to your
-- application: https://developer.github.com/v3/#user-agent-required
, apiVersion = "v3"
-- ^ Specifies the API version to query: https://developer.github.com/v3/media/
}
runGitHubT state $ do
-- Get information for the "master" branch
-- https://developer.github.com/v3/git/refs/#get-a-single-reference
ref <- queryGitHub GHEndpoint
{ method = GET
-- Colon-prefixed components in the endpoint will be interpolated by
-- the values in 'endpointVals'.
-- In this case, "/repos/alice/my-project/git/refs/heads/master"
, endpoint = "/repos/:owner/:repo/git/refs/:ref"
, endpointVals =
[ "owner" := "alice"
, "repo" := "my-project"
, "ref" := "heads/master"
]
, ghData = []
}
-- 'github-rest' provides a '.:' helper for when the API guarantees that a
-- key in a JSON object exists
--
-- The result of 'queryGitHub' is anything that's an instance of FromJSON,
-- if using manually-defined data types is preferred over using '.:'. This
-- package can be easily used with the aeson-schemas library, which
-- provides a type-safe way to query JSON data.
let sha :: Text
sha = ref .: "object" .: "sha"
-- Create a new branch called "foo"
-- https://developer.github.com/v3/git/refs/#create-a-reference
queryGitHub GHEndpoint
{ method = POST
, endpoint = "/repos/:owner/:repo/git/refs"
, endpointVals =
[ "owner" := "alice"
, "repo" := "my-project"
]
, ghData =
[ "ref" := "refs/heads/foo"
, "sha" := sha
]
}
```
## Comparison to other libraries
The `github` package provides a decent API for querying the GitHub API,
and it defines Haskell data types for each endpoint. These data types can
be used as the result of `queryGitHub`.
This package provides a different interface for people with different tastes:
* `github-rest` informs the user exactly which GitHub endpoint is being hit
(e.g. `/repos/:owner/:repo`). Users no longer need to spend time trying to
scour documentation to find the corresponding function for an endpoint.
* `github-rest` passes authentication once, with requests executed in a single
monadic context. The `github` package requires passing in an authentication
token every time a request is executed
* In the same vein, `github-rest` provides a monad transformer that handles all
GitHub state needed to execute `queryGitHub`. `github` runs everything in
`IO`, expecting the caller to keep track of GitHub state manually.
* `github-rest` allows usage with [`aeson-schemas`](http://hackage.haskell.org/package/aeson-schemas)