ApiBlaze: Designing the API Search Bar

  • SEA01 — Search for APIs by keyword

Data Model

{
"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": { ... }

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.
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 })
}
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 })
})

Index Page Design

<div class="container flex flex-center" id="root-container"></div>
.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>
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>
.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

  • ✅ SEA01 — Search for APIs by Keyword
  • ✅ FRAME01 — Controller & Routing
  • ✅ FRAME02 — Stateful Pages & Components
  • ✅ FRAME03 — Actions
  • ✅ FRAME04 — Optimized Bundling
  • ✅ TECH01 — Use PlainJS & Custom Framework
  • ✅ TECH02 — Use SAAS for CSS

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store