DZone
Microservices Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Microservices Zone > Quickstart OpenAPI With Ballerina

Quickstart OpenAPI With Ballerina

Let's explore what we can do with the open-source API format for describing and documenting (OpenAPI) specification by using the Ballerina programming language.

Anupama Pathirage user avatar by
Anupama Pathirage
CORE ·
Sep. 16, 21 · Microservices Zone · Tutorial
Like (4)
Save
Tweet
6.27K Views

Join the DZone community and get the full member experience.

Join For Free

What Is an API?

An Application Programming Interface (API) defines the allowed interactions between two pieces of software. It consists of the list of possible methods to call (requests to make), their parameters, return values, any data format they require, and many more. Here we focus on remote APIs, where the interacting parties run on separate machines and communicate over a network. APIs provide information hiding, and they can be thought of as an unbreakable contract.

Having API defined through a definition file is beneficial as:

  • It is both human and machine-readable specification and less prone to getting outdated.
  • Tools can use the API description to generate boilerplate code (in any programming language) to build provider and consumer applications.

What Is OpenAPI

OpenAPI Specification (formerly known as Swagger Specification) is an open-source format for describing and documenting APIs. The latest version of OpenAPI is 3.0. OpenAPI definitions can be written in JSON or YAML.

Swagger vs. OpenAPI

Swagger used to consist of the specification and a large ecosystem of tools to implement the specification.

The easiest way to understand the difference is:

  • OpenAPI = Specification
  • Swagger = Tools for implementing the specification

The Swagger toolset includes a mix of open-source, free, and commercial tools, which can be used at different stages of the API lifecycle, including editor, UI, codegen, Parser, etc.

In 2015, SmartBear Software donated the Swagger specification to the Linux Foundation and renamed the specification to the OpenAPI Specification. The development of the specification is fostered by the OpenAPI Initiative, which involves more than 30 organizations from different areas of the tech world, including Microsoft, Google, IBM, and CapitalOne and Smartbear Software, etc.

Since the Swagger tools were developed by the team involved in creating the original Swagger Specification, the tools are often still viewed as synonymous with the spec. But the Swagger tools are not the only tools that are available for implementing the OpenAPI Specification.

Advantages of Using OpenAPI

  • Design first approach and will lead to accurate service/client implementation
  • Provides collaborative API development as they are formalized plain-text documents.
  • Acts as a source of truth for API testing
  • Can avoid errors which get when writing boilerplate code
  • Save time

OpenAPI Document Structure

An OpenAPI document is a text file, commonly called openapi.json or openapi.yaml, representing a JSON object, in either JSON or YAML format.

The root object in any OpenAPI document is the OpenAPI Object. Only two of its fields are mandatory.

  • openapi — version of the OAS
  • info — general information about the API. The `title` and `version` fields are mandatory.

Additionally, at least one of the following fields is required:

  • paths — API Endpoints (also called Operations or Routes) are called Paths in the OAS.
  • components — store re-usable definitions that might appear in multiple places in your specification document
  • webhooks -The incoming webhooks that MAY be received as part of this API and the API consumer MAY choose to implement.

The Paths Field

  • API Endpoints are called Paths in the OAS and are represented by paths object.
  • Paths must start with a forward slash / since they are directly appended to the server URL o construct the full endpoint URL.
  • Every field in the Paths Object is a Path Item Object describing one API endpoint. The Path Item Object describes the HTTP operations that can be performed on a path with a separate Operation Object for each one.

A simple document structure (with some important fields only) is as follows:

YAML
 
openapi:
info:
 title:
 description:
 version:
paths:
 /weather:
   get:
     tags:
     summary:
     description:
     operationId:
     externalDocs:
     parameters:
     - name:
       in:
       description:
       schema:
         type:
     responses:
       200:
         description: 
         content:
           application/json:
             schema:
               title:
     deprecated:
     security:
     servers:
     requestBody:
     callbacks:


OpenAPI With Ballerina

Now let’s explore what we can do with OpenAPI using Ballerina programming language.

Note: If Ballerina is not installed already, follow the instructions and install Ballerina. Refer to the following video for more details.

The sample code in this article is using the Ballerina Swan Lake Beta2 version.


Ballerina supports the following modes of operations:

OpenAPI to Ballerina

If you already have an OpenApi Specification(OAS)-3 document for your service(s), you can use that contract to generate a Ballerina source code.

  • Client generation — Generates a Ballerina client endpoint for a provided OAS definition.
  • Service generation — Generates a mock version of the Ballerina service for a provided OAS definition.

Ballerina to OpenAPI

This allows generating an OpenAPI Specification(OAS) v3 definition of a Ballerina service.

Validate Service Implementation Against OpenAPI

The Ballerina OpenAPI compiler plugin validates the implementation of service against the specified OpenAPI contract during the compile time.

OpenAPI to Ballerina — Client Generation Example

In this post, I will explore the OpenAPI to Ballerina Client Generation scenario further. I am going to use a part of the disease.sh OpenAPI spec to generate a ballerina client from that. You can find a large number of clients generated for Ballerina language based on OpenAPI in the ballerinax-openapi-connectors repo.

Step 1: Save the following OpenAPI specification in a .yaml file:

YAML
 
openapi: "3.0.0"
servers:
  - url: https://disease.sh
info:
  version: 3.0.0
  title: Novel COVID-19 API - Disease.sh - An open API for disease-related statistics
  description: >
    This is a generated connector from [Novel COVID-19 API version 3.0.0](https://disease.sh/docs/) OpenAPI Specification.
    Ballerina connector for COVID-19 provides easy access to latest COVID-19 related data across the world. Please refer to [API documentation](https://disease.sh) for more detail.
  license:
    name: GNU V3
    url: 'https://github.com/disease-sh/API/blob/master/LICENSE'
  x-display:
    label: COVID-19
    iconPath: "resources/covid19.svg"
  x-init-description: |
    The connector initialization doesn't require setting the API credentials.
tags:
  - name: 'COVID-19: Worldometers'
    description: '(COVID-19 data sourced from Worldometers, updated every 10 minutes)'
  - name: 'COVID-19: Vaccine'
    description: '(COVID-19 vaccine trial data from raps.org, updated every 24 hours)'

paths:
  /v3/covid-19/all:
    get:
      tags:
        - 'COVID-19: Worldometers'
      operationId: getGlobalStatus
      x-display: 
        label: "Global Status"
      parameters:
        - name: yesterday
          description: Enter `true`(1) to receive data reported a day ago. Default is `false`(0)
          in: query
          schema:
            type: string
          x-display: 
            label: "Yesterday"
        - name: twoDaysAgo
          description: Enter `true`(1) to receive data reported two days ago. Default is `false`(0)
          in: query
          schema:
            type: string
          x-display: 
            label: "Two Days Ago"
        - name: allowNull
          in: query
          schema:
            type: string
          description: 'By default, value is 0. Enter `1` to allow nulls to be returned'
          x-display: 
            label: "Allow Null"
      summary: 'Get global COVID-19 totals for today, yesterday and two days ago.'
      responses:
        '200':
          description: Global COVID-19 status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CovidAll'
components:
  schemas:
    CovidAll:
      properties:
        updated:
          type: number
          description: Last updated timestamp
        cases:
          type: number
          description: Total cases
        todayCases:
          type: number
          description: Today cases
        deaths:
          type: number
          description: Total deaths
        todayDeaths:
          type: number
          description: Today deaths
        recovered:
          type: number
          description: Total recovered
        todayRecovered:
          type: number
          description: Today recovered
        active:
          type: number
          description: Active cases 
        critical:
          type: number
          description: Critical cases
        casesPerOneMillion:
          type: number
          description: Cases per one million
        deathsPerOneMillion:
          type: number
          description: Deaths per one million
        tests:
          type: number
          description: Total number of COVID-19 tests administered
        testsPerOneMillion:
          type: number
          description: COVID-19 tests for one million
        population:
          type: number
          description: World population
        oneCasePerPeople:
          type: number
          description: One case per people
        oneDeathPerPeople:
          type: number
          description: One deaths per people 
        oneTestPerPeople:
          type: number
          description: One tests per people 
        activePerOneMillion:
          type: number
          description: Active cases per one million
        recoveredPerOneMillion:
          type: number
          description: Recovered cases per one million
        criticalPerOneMillion:
          type: number
          description: Critical cases per one million 
        affectedCountries:
          type: number
          description: Affected countries 
      description: COVID-19 global status
externalDocs:
  description: Find out more about this API
  url: 'https://github.com/disease-sh/API'


Step 2: Navigate to the location where the .yaml file exists and create a new Ballerina project to place the source code of the client using the below command.

bal new client

It will create a folder named client with main.bal and Ballerina.toml file.

Ballerina project


Step 3: Generate the client Ballerina code using the following command.

bal openapi -i openapi.yaml — mode client -o client

The definition of the Ballerina openapi command is as follows.

bal openapi [-i | — input] <openapi-contract-file-path> [ — mode <mode-type>] [-o | — output] <output-location>

The output of the above command is:

Note: This is an experimental tool, which only supports a limited set of functionality.
Client generated successfully.
Following files were created.
-- client.bal
-- types.bal


It has created two new .bal files within the project folder.

The type.bal will contain the type definitions required for this code. The client.bal will contain the client implementation.

Ballerina Project - Client Ball


Step 4: Implement the client invocation code. Add the following code into the main.bal file:

Implementing Client Invocation Code

Step 5: Compile and run the Ballerina client package using the following command.

bal run client

You will see the output as follows which includes the COVID data.

Compiling source
 anupama/client:0.1.0Running executableGlobal Covid Data: {"updated":1630222838676.0,"cases":216770017.0,"todayCases":57222.0,"deaths":4508264.0,"todayDeaths":1396.0,"recovered":193703680.0,"todayRecovered":66956.0,"active":18558073.0,"critical":113386.0,"casesPerOneMillion":27810.0,"deathsPerOneMillion":578.4,"tests":3289818793.0,"testsPerOneMillion":419267.69,"population":7846583141.0,"oneCasePerPeople":0,"oneDeathPerPeople":0,"oneTestPerPeople":0,"activePerOneMillion":2365.12,"recoveredPerOneMillion":24686.37,"criticalPerOneMillion":14.45,"affectedCountries":223.0}

Summary

In this post, we’ve looked at how we can generate a client using an OpenAPI definition file with Ballerina language. The Ballerina openapi tool is still in the experimental stage. Especially the user experience and openAPI spec compliance related to OpenAPI to Ballerina service generation and Ballerina to OpenAPI will improve further in the upcoming releases.

Ballerina (programming language) API Open source Object (computer science)

Published at DZone with permission of Anupama Pathirage. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Comparing Approaches to Durability in Low Latency Messaging Queues
  • Sprint Goals: How to Write, Manage, and Achieve
  • No Sprint Goal, No Cohesion, No Collaboration
  • Geo What? A Quick Introduction to Geo-Distributed Apps

Comments

Microservices Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo