Hey there, fellow developer! Ready to dive into the world of Linear API integration with Go? You're in for a treat. Linear's API is a powerhouse for project management, and Go's simplicity makes this integration a breeze. Let's get cracking!
Before we jump in, make sure you've got:
Let's kick things off by creating a new Go module:
mkdir linear-api-integration cd linear-api-integration go mod init github.com/yourusername/linear-api-integration
Now, let's grab the HTTP client we'll need:
go get github.com/go-resty/resty/v2
Time to get that API key working for us. Create a new file called main.go
and let's set up our client:
package main import ( "github.com/go-resty/resty/v2" ) const baseURL = "https://api.linear.app/graphql" func main() { client := resty.New() client.SetHeader("Authorization", "YOUR_API_KEY_HERE") client.SetHeader("Content-Type", "application/json") }
Linear uses GraphQL, so our requests will be a bit different from typical REST APIs. Let's fetch some issues:
func getIssues(client *resty.Client) { query := ` query { issues { nodes { id title state { name } } } } ` resp, err := client.R(). SetBody(map[string]string{"query": query}). Post(baseURL) if err != nil { panic(err) } fmt.Println(resp.String()) }
Now, let's parse that JSON response:
type IssueResponse struct { Data struct { Issues struct { Nodes []struct { ID string `json:"id"` Title string `json:"title"` State struct { Name string `json:"name"` } `json:"state"` } `json:"nodes"` } `json:"issues"` } `json:"data"` } var issueResp IssueResponse err = json.Unmarshal(resp.Body(), &issueResp) if err != nil { panic(err) } for _, issue := range issueResp.Data.Issues.Nodes { fmt.Printf("Issue: %s, State: %s\n", issue.Title, issue.State.Name) }
Let's create an issue:
func createIssue(client *resty.Client, title string, description string) { mutation := fmt.Sprintf(` mutation { issueCreate(input: {title: "%s", description: "%s"}) { success issue { id title } } } `, title, description) resp, err := client.R(). SetBody(map[string]string{"query": mutation}). Post(baseURL) if err != nil { panic(err) } fmt.Println(resp.String()) }
Linear uses cursor-based pagination. Here's how to handle it:
func getIssuesWithPagination(client *resty.Client, cursor string) { query := fmt.Sprintf(` query { issues(first: 10, after: "%s") { pageInfo { hasNextPage endCursor } nodes { id title } } } `, cursor) // Make the request and handle the response as before }
For rate limiting, Linear is pretty generous, but it's good practice to add a small delay between requests:
time.Sleep(100 * time.Millisecond)
Don't forget to test! Here's a simple example:
func TestGetIssues(t *testing.T) { client := setupTestClient() issues := getIssues(client) assert.NotEmpty(t, issues, "Issues should not be empty") }
And there you have it! You've just built a solid Linear API integration in Go. Remember, this is just scratching the surface - Linear's API is packed with features for you to explore.
Keep coding, keep learning, and most importantly, have fun with it! If you hit any snags, the Linear API docs are your best friend. Now go forth and build something awesome!