Back

Reading and Writing Data Using the Linear API

Aug 13, 20248 minute read

Introduction

Hey there, fellow JavaScript devs! Ready to dive into the world of Linear API? If you're looking to build a slick user-facing integration that syncs data like a charm, you're in the right place. We'll walk through the ins and outs of reading and writing data using the Linear API, with a focus on keeping things snappy and efficient. Let's get started!

Setting up the Linear API Client

First things first, let's get our Linear API client up and running. It's a breeze, I promise!

npm install @linear/sdk

Now, let's set up our client:

import { LinearClient } from '@linear/sdk'; const linearClient = new LinearClient({ apiKey: 'your_api_key_here' });

Pro tip: For user-facing integrations, you might want to use OAuth instead of an API key. Linear's got your back with OAuth support, so check out their docs for the nitty-gritty details.

Reading Data from Linear

Alright, time to fetch some data! Let's grab some issues, shall we?

async function fetchIssues() { const issues = await linearClient.issues({ first: 50, filter: { state: { name: { eq: 'In Progress' } } } }); return issues.nodes; }

This little snippet will fetch the first 50 issues that are "In Progress". Cool, right? You can tweak the filter to get exactly what you need.

Writing Data to Linear

Now, let's create an issue and update it. It's just as easy as reading data!

async function createAndUpdateIssue() { // Create a new issue const newIssue = await linearClient.createIssue({ title: 'Fix that pesky bug', description: 'It\'s driving everyone nuts!', teamId: 'your_team_id' }); // Update the issue await linearClient.updateIssue(newIssue.id, { status: 'In Progress' }); }

Boom! You've just created an issue and updated its status. Linear's API is pretty intuitive, so you'll be a pro in no time.

Implementing Real-time Sync

Want to keep your integration up-to-the-second fresh? Webhooks are your new best friend.

import express from 'express'; const app = express(); app.post('/webhook', express.json(), (req, res) => { const { action, data } = req.body; if (action === 'create' && data.type === 'Issue') { console.log('New issue created:', data.title); // Do something with the new issue } res.sendStatus(200); }); app.listen(3000, () => console.log('Webhook listener running on port 3000'));

Set this up, and Linear will ping you whenever something interesting happens. No more constant polling needed!

Handling Pagination and Rate Limits

When you're dealing with a lot of data, pagination is your friend. Here's how to handle it like a pro:

async function fetchAllIssues() { let hasNextPage = true; let endCursor = null; const allIssues = []; while (hasNextPage) { const result = await linearClient.issues({ first: 100, after: endCursor }); allIssues.push(...result.nodes); hasNextPage = result.pageInfo.hasNextPage; endCursor = result.pageInfo.endCursor; } return allIssues; }

As for rate limits, Linear's pretty generous, but it's always good to keep an eye on them. The API returns rate limit info in the response headers, so you can throttle your requests if needed.

Error Handling and Retries

Nobody likes errors, but they happen. Here's a simple retry mechanism to keep your integration robust:

async function fetchWithRetry(fn, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await fn(); } catch (error) { if (i === maxRetries - 1) throw error; await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i))); } } } // Usage const issues = await fetchWithRetry(() => fetchIssues());

This will retry your function with exponential backoff. Neat, huh?

Optimizing Data Sync

Want to make your integration lightning fast? Caching is the way to go:

const cache = new Map(); async function fetchIssueWithCache(issueId) { if (cache.has(issueId)) { return cache.get(issueId); } const issue = await linearClient.issue(issueId); cache.set(issueId, issue); return issue; }

This simple cache will save you from making unnecessary API calls. Just remember to invalidate the cache when data changes!

Testing and Debugging

Testing your integration is crucial. Here's a quick example using Jest:

jest.mock('@linear/sdk'); test('fetchIssues returns issues', async () => { LinearClient.mockImplementation(() => ({ issues: jest.fn().mockResolvedValue({ nodes: [{ id: '1', title: 'Test Issue' }] }) })); const issues = await fetchIssues(); expect(issues).toHaveLength(1); expect(issues[0].title).toBe('Test Issue'); });

For debugging, don't forget to use Linear's API playground. It's a great way to test queries and mutations before implementing them in your code.

Conclusion

And there you have it! You're now equipped to build an awesome Linear integration. Remember to keep your code clean, handle errors gracefully, and always think about performance. The Linear API is powerful and flexible, so don't be afraid to experiment and push its limits.

Happy coding, and may your integrations always be in sync! 🚀