How to query specific line(s) from a file using GitHub APIs
Tags: node, github, tutorial, javascript
Published: 2021-05-10 19:21:07

---
title: How to query specific line(s) from a file using GitHub APIs
published: true
description: Querying specific lines from a file hosted on a github repo using REST APIs
tags: node, github, tutorial, javascript
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gd162sg8ciguzblctgci.jpg
---

# Permalinks

One of the neat features about GitHub is the generation of permalinks urls that highlights a range of line numbers. This is particularly useful when you want to highlight a chunk of code or a line to show it to someone else. 

To do so, just navigate to the file you want on github and click on one line, hit the `Shift` key and click on the end line for the code block. This generates a URL with the highlighted block content that you can then use for sharing.

![](https://media.giphy.com/media/G95PmK5apUwnpCynwL/giphy.gif)

**Edit: feedback based on comment**
Clicking on the start line number will show the ellipses  button `...` hold down shift and click on the end line number. Then click on the overflow button and select `Copy permalink`


**Tip:**
You can just add `#L{start_line}-L{end_line}` to the URL as follows
`https://github.com/{org_name}/{repo_name}/{path_to_file}#L{start_line}-L{end_line}`

Note: You can _perhaps_ do the same thing with other version control platforms like bitbucket or gitlabs but I have not checked.

# Show me the API!

I was recently working on a project that dynamically generates code snippet from files hosted on github. Naturally, I referred to GitHub's APIs to query file content. Simple right? Well let's dig deeper into it. 

Navigating through [Github's APIs](https://docs.github.com/en/rest), I was disappointed to find out there is no API that query a **specific line number(s)** from a file. The [Search API](https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github) only allows to query the full content of the file. No problem, let's dig into coding logic for post processing.

![](https://media.giphy.com/media/llKJGxQ1ESmac/giphy.gif)

# Show me the code! 

To bypass this limitation, I was able to fetch the content of the file using the SearchAPI as follows

```js
async function fetchContent(orgName, repoName, file, ref) {
  const baseURL = `https://api.github.com/repos/${orgName}/${repoName}/contents/${file}?ref=${ref}`
  let res = await fetch(baseURL).catch(err => {
    throw new Error(`Error fetching content from ${baseURL}. ${err}`)
  })

  if (!res.ok){
    throw new Error(`Response status from ${baseURL}: ${res.status}`)
  }

  let body = await res.text()
  // Content body from github is base64 encoded
  return Base64.decode(JSON.parse(body).content)
}

let content = await fetchContent(orgName, repoName, file, ref)
```
This brings in the whole file as text with new line delimiters presented as `\n`. You see where I'm going with this 👀

From here, you can `split()` the text content using `\n` as the separator and store it in an array

```js
content = content.split('\n')
```

And then simply generate the snippet using a `getSlice(content,range)` method

```js
let snippet = getSlice(content,range)
```

Where getSlice is defined as follows

```js
// Splits the content given the range a-b or just line number a
const getSlice = (content, range) => {
  if (range.includes('-')){
    var a = range.split("-")[0] - 1
    var b = range.split("-")[1]
    return content.slice(a,b).join('\r\n')
  } else if (parseInt(range)) {
    return content[parseInt(range)-1]
  }
}
```

Note: range is passed as a string with a `-` delimiter between the start_line and end_line

And thats it! 

# What about you?

Did you find this useful? I am curious to know if anyone has another approach for this since GitHub does not have an API to do so (yet!)