Monthly Archives :

February 2022

API Design – Attributes of a Quality API

API Design – Attributes of a Quality API 1920 1080 ELVT Consulting

By: Daniel Ors, Gabe Martinez

Series Introduction

An essential aspect of our massive software world is collaboration. Everything from open source software communities, product integrations, and even microservice communications require collaboration to be successful. Software, and its continued development, rely on the collaborative efforts of those generating it to truly scale into large user adoption. When it comes to communication about software and its development, effective APIs (Application Programming Interfaces), and their corresponding documentation, are crucial to the development of a successful application. In this series we will cover the core attributes of a quality API as well as how to construct effective APIs that support efficient adoption both internally and by external 3rd-parties.

An API is a defined method of interacting with a specific software application describing standardized request formats and what to expect in return for each request type. Since the format for requests is frequently strictly defined, it makes it essential that the documentation is clear, unambiguous, and accurately updated over time. This allows developers to work with unfamiliar systems in a standardized way with zero to minimal involvement from the creator of the API itself. If you’re interested in reading more about the basics of APIs in plain English, FreeCodeCamp has an excellent blog post on the subject.

Over the coming weeks we’ll be taking a deep dive into the key components of designing a successful API — from how specific API attributes make them compelling and easy to work with, to creating your own starting point for an API, as well as an all comers’ guide to how to use an API. We will begin with an examination of the Attributes of a Quality API, then the ins and outs of API Design, and conclude with a deep dive into how to Document your API to maximize its potential and usage.

Attributes of a Quality API

Quality APIs are identified by several notable attributes:

  • Clear Purpose
  • Strong Documentation that is Easy to Understand
  • Well-defined and Discrete Endpoints
  • Rich Data that Presents Significant Value to the Developer and End User
  • Potential for Extensibility in the Open Source Community
  • Conform to an Established Conventional API Architectural Style (e.g. REST, GraphQL, RPC, Falcor, etc.)
    • How these concepts help craft more maintainable APIs
  • Strong Community Supporting its Development via Active Repository Management
  • Standards for Maintaining
  • Graceful Error Handling
  • Solid Security Practices

An API does not require all of these attributes to possess quality or potential, but the very best APIs all adhere to these principles when building out their functionality. If you are getting started with your API, these are clear goals to strive for in getting it off the ground.

Clear Purpose

Good APIs will have a clear mission statement that outlines the goals and objectives of its functionality. Without standards for maintaining and a strong community understanding of the API’s purpose, its long-term dependability will be very low, as it will appear that the core maintainers do not have strong investment in the success of their API. In addition, the intended audience for the API should only influence who it is made available to — all standards for quality mentioned here will apply to any of the most common types of APIs — private, public, or commercial (also known as partner APIs).

Strong Documentation

Documentation of functionality that is easy to understand is critical to the success of any API. It is essential that the documentation is also not overly succinct in providing understandable instructions, but rather balancing detail with clarity. Without documentation, an API will be nearly impossible to access, and it will be difficult to parse what data, endpoints, or feature frameworks are available to use. This is a frequent issue with closed APIs, where the core users are a limited group of developers that hold all the keys to the castle in terms of knowledge. In this scenario, when new members of the team are introduced to the API, it is unlikely that quality contributions will be produced by the new developer unless the API is well-documented. Person-to-person knowledge transfer is a poor substitute for clear documentation, as clear documentation will always allow for a more transparent and complete picture to be communicated and provides a persistent resource available for reference.

Well-Defined, Discrete Endpoints

Many APIs allow significant overlap in their data and endpoints, which, depending on the subject matter, may be appropriate. However, distinguishing between data areas has value in charting out your API. Discrete endpoints will prevent developers from getting bogged down in individual features, digging down into infinite JSON soup for applicable data for their use case. This improves usability significantly for your audience.

It is important to design and define these endpoints so that developers will have clear expectations for access and delivery of data. For example, if you have an API that routinely updates current information about a company in its own endpoint, and has a separate data endpoint for employees, it is better to only allow end users to request employee data from the top level employee endpoint (over which you will have more fine-tuned throttling control), rather than having unrestricted access to a separate api/company/employees endpoint. By restricting access to specific endpoints and resources, it will prevent misuse of your dataset and API, and improve the cost of hosting and maintaining it. This can be achieved by including clear rate limits for each endpoint in your documentation along with your authentication protocol for accessing the API.

Rich Data that Presents Significant Value

Without data that presents value to the developer and the user, an API will surely wallow in obscurity — whether it is being built as a personal project or for an organizational purpose. If there is a single use case for the API you are thinking about, that clearly does not exist yet, it is far more likely that a parallel or adjacent API will be available to support development of your idea. Extending that API’s functionality to include yours may also present a more significant value-add to your own resume or organization’s reputation in the marketplace.

Potential for Extensibility in the Open Source Community

Without future potential for innovation, APIs will likely become largely stagnant and more focused on issue handling rather than providing room for growth. It is important to keep an eye on the horizon for the roadmap you envision for your API, or what the community suggests would represent quality additions to the feature set. Your stakeholders — whether they are private clients or the open source community — will have a vested interest in contributing to your API’s improvements and future viability.

Conform to an Established Conventional API Architectural Style

There are several standard API architectural patterns that have emerged over years, from REST, SOAP, GraphQL, to RPC. While it is important which format you pick for modeling your API on, it is also critical that you make it clear in your documentation that it follows that convention. This will aid developers significantly in picking up your API and understanding its design, expectations, and, of course, quirks!

When you invest in following a particular API architectural pattern, it also improves the ability of your own engineers, as well as any potential open source developers, to maintain and extend the functionality of your application. This presents a very strong value-add for your organization’s product and its viability as a solution in the long-term.

Using accepted conventions of API style will also aid in its long-term viability and maintainability. In conforming to a pattern, a wider range of developers and engineers will quickly be able to jump in, identify solutions, and become a key contributor. It will aid in developer retention and overall productivity — the easier and more rewarding you make it for individuals to contribute and be an active member of the community, whether open or closed source, the more likely you are to reap exponential rewards.

Strong Community Supporting Development in Github/GitLab

Hosting and managing your API via active repository management and diligent issue documentation and management is crucial. This practice allows active developers, internal and external, to contribute to open issues and gain increased familiarity with your technology and expectations. This also allows you to better manage releases of your API, protecting your stable code branch while enabling feature enhancements and extensions of functionality to be tested in less stable branches.

Using a heavily trafficked versioning tool such as Github or GitLab will also encourage growth opportunities as they increasingly move to a more sophisticated social format for hosting code repositories, particularly open source repositories.

Standards for Maintaining

Setting baseline standards for your API is key to ensuring quality maintenance and fulfillment of the product roadmap. It will also make it easier for developers to contribute, as clear expectations will be present for issue resolution as well as feature requests.

Your standards should include several key points — a style guide for code, expectations for contributing, resources required, and rules for communication along with key maintainers.

A style guide will make it clear which specific conventions should be followed in submitting contributions to the codebase. This should include basics such as standard naming conventions, giving priority to commenting new code with sufficient detail, and best practices for specific syntax within the majority programming language being used in your API. Airbnb’s style guide for JavaScript is an excellent example of a strong syntaxical standard.

Your section on expectations for contributing should demonstrate what a proper contribution process will look like — how to identify a suitable open issue to address, whether tests are required, and general timeframe for when to expect approvals or responses from key maintainers. (ex: “Our team spends about 10 hours per week on this project, average response time is 5-7 days.”)

A section covering the resource requirements to get started maintaining will also encourage developers to invest their time — as it will lower the bar to contributing significantly. By documenting your processes and what tools are used by the core team, it will be easier for new contributors to quickly get comfortable with the code and complete their submissions. This is an opportunity to document any existing known issues for developers in working with the project’s standard resources, allowing others to suggest new solutions from their own experience.

Rules for communication will provide clear guidelines for what should be communicated in the contribution process — from reasonable pull requests to what is allowed in the slack/gitter channel for the project. One key requirement that is common to most shared projects is that all decisions, support requests, or feature requests should be submitted in public channels, so that transparent communication is present to all involved. These standards will streamline moderation and management of project channels. Along with these guidelines, a list of key maintainers and project managers should be included. This will add points of contact to relieve pain points if the standard contribution process does not proceed as expected. 

Homebrew’s open source repository follows these principles and provides excellent examples with their Code of Conduct and Contributing Guide.

Graceful Error Handling

As your primary audience and user base will be developers, it is important that you provide for detailed error handling along with graceful exiting. It will be a far more dev-friendly experience to end the terminally errored process when it reaches the error state — using conventions such as try/catch blocks to end the connection or request/response operation. It is also key to use specific error handling messages that are informative, concise, and provide the correct level of detail to enable successful troubleshooting.

Solid Security Practices

In order to protect developers, users, and yourself from exposed and non-encrypted connections where API keys and other secrets could be easily transcribed, you should make it a requirement to use security practices such as SSL-only connections and using secure authentication methods such as OAuth to verify access.

Wrapping Up

If you’ve followed these key steps in building your API, congratulations! You’ve very likely created a strong application that will encourage future development, extension, and user growth. The most critical next step to take is to continue to invest time in cultivating your API’s contributions and release roadmap. Focusing on maintaining the release cycle will ensure continually increased quality of service for both developers and end users.

This series will be continued in next week’s installment, How to Design a Robust API.

By: Daniel Ors, Gabe Martinez

Designing with Grids

Designing with Grids 1500 844 ELVT Consulting

By: Dimitri Tenke Fokoua, Siva Nammi

Designing a whole web page or sometimes just an input field can be very challenging depending on the approach we take. In today’s development world, and in the frontend in particular, everything can be its own component. Having in mind that everything can be considered a table or container can make your life as a developer a whole lot easier! In this blog we will go over some examples on how we can design about anything with this approach and use flex to style it.

Grid Layout

Everything is a table! When designing a component, a tab or a whole page, a very useful way is to divide them into multiple tables. This provides a flexible structure to your User Interface and ultimately results in a clean experience for the User. In angular, for example, a very easy way to accomplish such a task would be using the angular Fx Layout. Let’s try to build a very simple top bar menu component with dropdowns.

First we need to define the main direction we want to give to our component. In our case, the menu is going left-to-right and we will also have dropdowns that will show under the menu. In such a situation, our direction will be column, or top-to-bottom using the Angular directive FxLayout.

Example:

<div fxLayout="column"></div>

In this main container, every included container will appear top-to-bottom. But the main menu bar we want should be showing left-to-right! To solve this, we can nest tables and give it different directions as we wish.

Example:

<div id=’main-container’  fxLayout="column">
     <div id=’row-container’ fxLayout="row" >
<div>Option1</div>
<div>Option2</div>
<div>Option3</div>
<div>Option4</div>
<div>Option5</div>
<div>Option6</div>
      </div>
</div>

In the above example the nested container ‘row-container’ will have a row direction meaning left-to-right, thus everything within this container will appear from left-to-right. Pretty easy for the menu bar that just contains items from left-to-right.

What about the dropdown that will not only go left-to-right for each menu item, but also may contain multiple items going top-to-bottom? For this case we can take advantage of the Angular Grid System

Continuing to build off of our above example, in the main container we want the second row to be the dropdown and only show upon click. We can think of it like a big table that will be divided in rows and columns then use the appropriate space we want to allocate to any part of it.

Example:

 <div id=’main-container’  fxLayout="column">

     <div id=’row-container’ fxLayout="row" >

<div>Option1</div>

<div>Option2</div>

      </div>

    <div id=’dropdown-container’  gdColumns="1fr 1fr 1fr 1fr 1fr 1fr" gdRows="1fr 1fr 2fr">

    </div>

</div>

In the ‘dropdown-container’ we defined a set of 6 columns that will all be equal in terms of width and a set of 3 rows where the first and second rows will equally take 1 fraction of the space and the third will take 2 fractions. In this grid, you can position anything anywhere by giving it an axis position coordinate using gdColumn and gdRow.

Example:

<div id=’dropdown-container’  gdColumns="1fr 1fr 1fr 1fr 1fr 1fr" gdRows="1fr 1fr 2fr">

<div  gdColumn="1" gdRow="1">dropdown1</div>

<div  gdColumn="2" gdRow="2">dropdown2</div>

<div  gdColumn="3" gdRow="2">dropdown3</div>

<div  gdColumn="4" gdRow="1/3">dropdown4</div>

<div  gdColumn="5" gdRow="2">dropdown5</div>

<div  gdColumn="6" gdRow="1/4">dropdown6</div>

</div>

In this example the first element (container) will take column 1 and row 1 position (*Picture-1).

Picture-1

The second element will be located in the second column second row (*Picture-2).

Picture-2

The fourth element will be in the fourth column and take row 1 to 3 which in this case will be the first two rows (*picture-3).

Picture-3

The sixth element here will take the last column and all available rows (*picture-4).

Picture-4

With this method, you can pretty much design everything on a page and place elements anywhere you want in a structured and orderly manner. Now you can start with styling it and hiding/showing it appropriately.

Now we’ll take a look at what can be done using Flex-Box.

Flex-Box

As discussed above, Grid Layout has been designed to work alongside other parts of CSS, as part of a complete system for doing the layout. In this section, I will explain how a grid fits together with Flexbox.

Grid and Flex-Box:

The basic difference between CSS Grid Layout and CSS Flexbox Layout is that flexbox was designed for layout in one dimension – either a row or a column. Grid was designed for two-dimensional layout – rows, and columns at the same time.

One-Dimensional Versus Two-Dimensional Layout:

A simple example can demonstrate the difference between one- and two-dimensional layouts.

In this first example, I am using flexbox to lay out a set of boxes. I have five child items in my container, and I have given the flex properties values so that they can grow and shrink from a flex-basis of 150 pixels.

I have also set the flex-wrap property to wrap, so that if the space in the container becomes too narrow to maintain the flex basis, the items will wrap onto a new row.

<div class="wrapper">

  <div>One</div>

  <div>Two</div>

  <div>Three</div>

  <div>Four</div>

  <div>Five</div>

</div>




.wrapper {

  width: 500px;

  display: flex;

  flex-wrap: wrap;

}

.wrapper > div {

  flex: 1 1 150px;

}

In the image, you can see that two items have wrapped onto a new line. These items are sharing the available space and not lining up underneath the items above. This is because when you wrap flex items each new row (or column when working by column) is an independent flex line in the flex container. Space distribution happens across the flex line.

A common question then is how to make those items line up? This is where you want a two-dimensional layout method: You want to control the alignment by row and column, and this is where grid comes in.

A couple simple questions to ask yourself when deciding between grid or Flex-Box is:

  • Do I only need to control the layout by row or column
    – use a Flex-Box
  • Do I need to control the layout by row and column
    – use a Grid

Content Out or Layout in?

In addition to the one-dimensional versus two-dimensional distinction, there is another way to decide if you should use flexbox or grid for a layout. Flexbox works from the content out. An ideal use case for flexbox is when you have a set of items and want to space them out evenly in a container. You let the size of the content decide how much individual space each item takes up. If the items wrap onto a new line, they will work out their spacing based on their size and the available space on that line.

Grid works from the layout in. When you use CSS Grid Layout you create a layout and then you place items into it, or you allow the auto-placement rules to place the items into the grid cells according to that strict grid. It is possible to create tracks that respond to the size of the content, however, they will also change the entire track.

If you are using Flex-Box and find yourself disabling some of the flexibility, you probably need to use CSS Grid Layout. An example would be if you are setting a percentage width on a flex item to make it line up with other items in a row above. In that case, a grid is likely to be a better choice.

Now that we have a better understanding of when to choose grid over Flex-Box or vice versa, let’s dive in deep with what Flex-Box offers us to make our lives easier.

Terminology:

  • Main Axis The main axis of a flex container is the primary axis along which flex items are laid out. Beware, it is not necessarily horizontal; it depends on the flex-direction property (see below).
  • Main-Start | Main-End The flex items are placed within the container starting from main-start and going to main-end.
  • Main Size A flex item’s width or height, whichever is in the main dimension, is the item’s main size. The flex item’s main size property is either the ‘width’ or ‘height’ property, whichever is in the main dimension.
  • Cross Axis The axis perpendicular to the main axis is called the cross axis. Its direction depends on the main axis direction.
  • Cross-Start | Cross-End Flex lines are filled with items and placed into the container starting on the cross-start side of the flex container and going toward the cross-end side.
  • Cross Size – The width or height of a flex item, whichever is in the cross dimension, is the item’s cross size. The cross size property is whichever of ‘width’ or ‘height’ that is in the cross dimension.

Flex Box Properties:

Properties are specific for flex containers and flex items.

Parent Properties:

  • Display:  It enables a flex context for all its direct children.
  • Flex-direction:  This establishes the main-axis, thus defining the direction flex items are placed in the flex container. 
  • Justify-Content:  This defines the alignment along the main axis.
  • Align-Items:  This defines the default behavior for how flex items are laid out along the cross axis on the current line.

Code Samples

Let us consider the previous dropdown container example that we covered in the previous Grid Layout section. Dropdown at option6 is a container which has 3 items in it. Let’s look at different layouts.

<div class="container" fxLayout="row"  fxLayoutAlign="start start">

 <div class="child-1">1. One</div>

 <div class="child-2">2. Two</div>

 <div class="child-3">3. Three</div>

</div>

Children Properties:

  • Order:  By default, flex items are laid out in the source order. However, the order property controls the order in which they appear in the flex container.
  • Flex-Grow: This defines the ability for a flex item to grow if necessary.
  • Flex-Shrink: This defines the ability for a flex item to shrink if necessary.
  • Flex-Basis: This defines the default size of an element before the remaining space is distributed.

Code Samples

<div class="container" fxLayout="row"  fxLayoutAlign="center stretch">

 <div class="child-1" style="order: 3;">1. One</div>

 <div class="child-2" style="order: 2;">2. Two</div>

 <div class="child-3" style="order: 1;">3. Three</div>

</div>

<div class="container" fxLayout="row" fxLayoutAlign="start stretch">
<div class="child-1" fxFlex='auto'>1. One</div>
<div class="child-2" fxFlex=30>2. Two</div>
<div class="child-3" fxFlex=20>3. Three</div>
</div>

The Conclusion

Flexbox and CSS Grid are both great, but neither one is a replacement for the other. They are best used together to create clean, manageable, and flexible web pages. Use the bullets below as a guide for when to use each:

  • CSS Grid is best used for two-dimensional layouts, meaning columns and rows. Think big picture, and overall layout of the page.
  • Flex-Box works best in one-dimension (columns or rows). Think of individual content areas, such as a menu or sidebar.

With almost full browser support, CSS Grid will be a necessary skill for front-end developers to learn and master.

By: Dimitri Tenke Fokoua, Siva Nammi