ApiBlaze: Designing the API Search Bar

ApiBlaze is a tool to explore API specifications: Search for a keyword, filter for objects, properties, or endpoints, and immediately see descriptions and code examples. ApiBlaze helps you to answer a specific question about an API lightning fast. You can try it here: apiblaze.admantium.com.

In the last article about ApiBlaze, I described how the general refactoring of my early ApiBlaze prototype happened in order to use my custom JavaScript framework called SPAC. When ApiBlaze is started, the first page is the API search. It features a central UI element: The search bar. After a few keystrokes, the user input is compared with the set of OpenAPI specifications. You see the API names, a small icon, and its description. The user input is highlighted in these results. Then, by clicking on one of the search results, or by using the navigational arrow keys, you can browse and select an API.

With these features, the following requirements will be fulfilled:

  • SEA01 — Search for APIs by keyword

In the next sections, we will detail the implementation, beginning with the data model and search functions, and finishing with the HTML and CSS of the page.

This article originally appeared at my blog.

Data Model

Let’s take a look at an example to figure out where to search in an OpenAPI specification and in which data fields the search should be done. Here is a short example of the Slack API.

{
"externalDocs": {
"description": "Learn more about the Slack Web API",
"url": "https://api.slack.com/web"
},
"host": "slack.com",
"info": {
"contact": {
"name": "Slack developer relations",
"url": "https://api.slack.com/support"
},
"description": "One way to interact with the Slack platform is its HTTP RPC-based Web API, a collection of methods requiring OAuth 2.0-based user, bot, or workspace tokens blessed with related OAuth scopes.",
"title": "Slack Web API",
"version": "1.5.0"
}
"basePath": "/api",
"paths": { ... },
"definitions": { ... }

The challenge with OpenAPI specifications is that the majority of its fields are optional — except the sections paths and definitions that contain the API details. Therefore, the search model is the complete API specification expect the paths and definitions sections.

Search Function

  • build a stringified representation of the API specification
  • build a list of matches that includes all APIs in which the users keyword(s) occur
  • rank the search results by the number of occurrences.

The first two steps can be handled by a function as shown here:

const matches = []
const scoredMatches = []
// traverse all apis, save matches
for (const [apiName, apiInfo] of Object.entries(apiList)) {
delete apiInfo.definitions
delete apiInfo.paths
const apiText = JSON.stringify(apiInfo) const nameMatch = apiName.match(keywords)
const apiInfoMatch = apiText.match(keywords)
if (nameMatch || apiInfoMatch) matches.push({ apiName, apiInfo })
}

The third step is realized by forming a regular expression of the keyword and counting the number of matches.

matches.forEach(api => {
const { apiName, apiInfo } = api
const searchText = apiName + ' ' + JSON.stringify(apiInfo)
const score = searchText.match(new RegExp(keywords, 'mig')).length
const apiDescription =
apiInfo.info && apiInfo.info.description
? apiInfo.info.description
: apiName
scoredMatches.push({ apiName, apiDescription, score })
})

The data model is done — lets continue with the design.

Index Page Design

<div class="container flex flex-center" id="root-container"></div>

The styling for the page uses a dark background, bright fonts and highlight colors. The container is displayed as flex with its items centered.

.container {
background-color: #292c36;
border-radius: $border-radius;
}
.flex {
display: flex;
}
.flex-center {
align-items: center;
justify-content: center;
}

API Search Page Design

<section>
<div id"api-spec-search-bar" class="api-spec-search-bar"></div>
<div id"api-spec-search-results" class="api-spec-search-results"></div>
</section>

Search Bar Component

<div id"api-spec-search-bar" class="api-spec-search-bar">
<h2>Load an API</h2>
<input type="text" id="api-spec-search-bar" placeholder="" value="" spellcheck="false" />
</div>

The search bar has conventional styling effects: Its border is accentuated when the element is highlighted

The visual aspects of the search bar are its fonts and its hover/focus effect.

api-spec-search-bar {
width: 400px;
padding: 10px;
background-color: #1d212b;
margin: 10px 10px;
color: #ccc;
border: 1px solid transparent;
box-shadow: 0 0 5px inset rgba(0, 0, 0, 0.2);
&:focus,
&:active,
&:hover {
color: #fff;
border: 1px solid #09f;
outline: 0;
box-shadow: 0 0 5px inset rgba(255, 255, 255, 0.2);
}
}

Search Results Component

<div id"api-spec-search-results" class="api-spec-search-results">
<a>
<i>{{ $icon }}</i>
<span class="heading">Kubernetes</span>
<span class="description">The core of Kubernetes control plane is the API server. The API server exposes an HTTP API that lets end users, different parts of your cluster, and external components communicate with one another.</span>
</a>
</div>

The styling is more complex: The icon and the .heading span are rendered on the same line, with a custom color. The .description is displayed in an emphasized font type. Hover effects accentuate the element.

.api-search-results {
text-align: left;
width: 400px;
background-color: #303644;
color: #ccc;
a {
display: inline-block;
cursor: pointer;
padding: 5px;
&:focus,
&:active,
&:hover {
color: #fff;
background-color: #424959;
outline: 0;
box-shadow: 0 0 5px inset rgba(255, 255, 255, 0.2);
> i {
opacity: 1;
}
}
i {
padding: 3px 5px;
width: $action-icon-size;
...;
}
.heading {
color: $search-result-heading-color;
}
.description {
display: block;
font-style: italic;
text-align: justify;
font-size: smaller;
}
}
}

Preview

Review: ApiBlaze Project Requirements

Searching for APIS

  • ✅ SEA01 — Search for APIs by Keyword

Framework

  • ✅ FRAME01 — Controller & Routing
  • ✅ FRAME02 — Stateful Pages & Components
  • ✅ FRAME03 — Actions
  • ✅ FRAME04 — Optimized Bundling

Technologies

  • ✅ TECH01 — Use PlainJS & Custom Framework
  • ✅ TECH02 — Use SAAS for CSS

Conclusion

IT Project Manager & Developer