This application demonstrates how to use a modern tech stack to build a real-time search UI to view Github repositories.
- React Hooks
Github implements their v4 API entirely in GraphQL. This challenge requires using v3, so this app implements
apollo-link-rest. For license types I have added
any to search for repositories of any license. This is logical because by default the user will search for repos of any type. Forcing them to reload the app to search for repos of any license type seems less than ideal.
This demo application shows how to build an application from create-react-app, to an application that allows the user to search for github repositories, and filter the results. This demonstrates how to allow the developer to use GraphQL queries in their React components, without a need for a GraphQL server.
Using Rest with Apollo
RestLink constructor, while passing it our endpoint url. Now we can use GraphQL queries in our React components. This example demonstrates how to use a function instead of a class, so we can avoid the overhead of instantiating our class. We wrap our component with
ApolloProvider, our higher-ordered component (HOC).
Our Search Container Component uses React
useReducer hook, to manage the state of our application, and the state of the queries sent to our API endpoints. Our GraphQL query takes the arguments passed to the endpoint. We create a HOC and pass our
ShowResults component to the named export from
react-apollo, graphql. We pass properties from our container component to our HOC, which returns these as props in our
Showing Search Results
Our component that handles showing search results, defines public methods for handling the filtering logic, so we can write unit-tests for these functions. This takes the data returned from our query component, filters the data, and shows it in the list.
The look and feel is a theme built on top of Ant Design, with CSS Modules stylesheets. In some instances CSS-in-JS may be used. Styled Components and Emotion are great solutions to handle styling, but CSS Modules is less effort with minimal styles.
apollo-link-rest is one way to be able to use GraphQL queries in React, while staying completely in the client side working with REST endpoints.
This means theoretically we can upgrade to their v4 API by just configuring our Apollo Client.
Configuring the Apollo Client makes it easy to switch back and forth from using endpoints and GraphQL servers.
This implementation is built as a real-time app, by default. We have explicitly told it not to be. For example,we have two states for each field, the
searchTextVal and the
searchText. If we want this to be real-time we can set
searchText instead of
searchTextVal and everytime the user types, a new search will be invoked. The Apollo Client handles this for us, so we don't have to do it manually.
In other words, we need to store two states for each field. One to represent the controlled form state, and another to specify the state that is synced with the server. Without this, then this would update the search results as we type, which would mean we wouldn't need a button to submit the search. This is not necessarily better or worse, but the interaction is different.
Build a Github repository search UI, using the following endpoint from the Github API: https://developer.github.com/v3/search/#search-repositories.
The UI should consist of two elements:
- a form for specifying search parameters - results from the latest search
The form should include the following fields:
- Text - a text box for full-text search queries, maps to the
- Stars - a text box that maps to the
starsqualifier and supports the syntax specified here. If the syntax of the text is invalid upon blur, an inline error message should be displayed.
- License - a dropdown that maps to the
licensequalifier, and includes the MIT, ISC, Apache and GPL license types (using details listed here)
- Include Forked - a checkbox that sets the
forkqualifier to "true"
Fields should be validated in a user friendly manner.
A search should only be initiated when the user submits the form with valid field entries.
Each result should include the following data:
- Repo name
- Repo owner's name
- URL to the repo
- Number of stars
- Whether or not the repo is forked
While results are loading from the API, all buttons and links in the UI should be disabled and a loading indicator should be displayed. If a search returns no results, that should be explicitly indicated in the results section.
The UI should support setting form fields and the current page via query parameters. Also, whenever the user searches or clicks, the URL should be updated with the appropriate query parameters.