Github is a remote source control solution that can act as a source of truth and remote backup for your local versioning system, in this case Git.
It makes development and collaboration when working in small to large codebases and has a handy web client that offers you all the tools .
But as a developer you're bound to want more or a very specific layout that's not supported in their native implementation , and hats where APIs come in , Github has one of the best APIs i've tinkered with .this tutorial will start off with the REST implementation then we'll switch to their GraphQL api final project
for starters i'd recommend setting up an api testing environment
and before we do that we'll also need a personal access token
then we'll an api client like postman or it's alternatives
and set the token in the header as such
remember to space the keyword Bearer to the actual token and
also add the application/json as shown below
and for example hitting the endpoint https://api.github.com/user will give you back the currently logged in user
and with that set up you can now experiment with queries even and make sure they work before using them .
Once sure of that we can start setting up react ,in this case i used axios with react-query
and the above query would look something like this
type casting query.data to MainAuthedUser to give us the type checking when using this in the code.
I generated the types manually by pasting the json response to json-to-ts
And viola.
this works fine but you'll notice we're barely using 30% of the json returned which is where GraphQL shines by only requesting what we need it also has more data because of it;s flexible nature
Let's take the user query for example
"login":"tigawanna","id":72096712,"node_id":"MDQ6VXNlcjcyMDk2NzEy","avatar_url":"https://avatars.githubusercontent.com/u/72096712?v=4","gravatar_id":"","url":"https://api.github.com/users/tigawanna","html_url":"https://github.com/tigawanna","followers_url":"https://api.github.com/users/tigawanna/followers","following_url":"https://api.github.com/users/tigawanna/following{/other_user}","gists_url":"https://api.github.com/users/tigawanna/gists{/gist_id}","starred_url":"https://api.github.com/users/tigawanna/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tigawanna/subscriptions","organizations_url":"https://api.github.com/users/tigawanna/orgs","repos_url":"https://api.github.com/users/tigawanna/repos","events_url":"https://api.github.com/users/tigawanna/events{/privacy}","received_events_url":"https://api.github.com/users/tigawanna/received_events","type":"User","site_admin":false,"name":"Dennis kinuthia","company":null,"blog":"https://next-portfolio-zeta-two.vercel.app/","location":"Nairobi Kenya ","email":"denniskinuthiaw@gmail.com","hireable":null,"bio":"React GraphQL Node Go","twitter_username":null,"public_repos":49,"public_gists":0,"followers":11,"following":39,"created_at":"2020-09-29T17:03:46Z","updated_at":"2022-09-01T21:26:46Z","private_gists":0,"total_private_repos":6,"owned_private_repos":6,"disk_usage":47541,"collaborators":0,"two_factor_authentication":false,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":10000}
This is quite the response and you'll notice that it has the
followers and following url which will point you to an endpoint
with the list of them
My objective was to have something like this , because i wanted this app to make discovering other users and their projects easier
The issue is it doesn't have information on whether I am following the user in order to know whether to show a follow or unfollow button.
so i used this work around
query 1 : to find if user is following another user , returns success if yes and 404 if false
query 2 - the main query that will go through the array of followers urls and for each one pause to make an async call to check follow status and insert it into the final object then push it into an array
exportconstgetUserWithFollowingDetails=async (token:string,url:string,username:string)=>{//console.log("user with following details ", username, url);letfollowers:any=[]constusers=awaitgetAuthedUserFollowers(token,url)asFollower[]forawait (constuserofusers){// //console.log("user with following details ",username,user.login);//@ts-ignoreuser.following_me=awaitgetIsUserFollowingMe(token,username,user.login).catch((e)=>{})followers.push(user)}returnfollowers}
Not only is this technique noticeably slower but will also burn through your rate limit very fast , and given the point of the app is to go deep into user profiles and fall deeper as you check who's following who and what repos they're working on you'll get timed out really fast
You could side step all of this and just remove the feature and only fetch those details if the follower card is clicked on or switch to the GraphQL api which unlocks some very handy features