Skip to main content

Konfig vs. Open Source

· 6 min read
Dylan Huang
Anh-Tuan Bui

Konfig vs. Open Source

Konfig offers numerous benefits when generating SDKs from OpenAPI compared to utilizing an open-source library or crafting them manually. These benefits significantly impact your engineers and business in a positive manner. In this article, we will outline these crucial advantages.

Key Advantages

Konfig offers 3 key advantages over the two most popular open source libraries for generating SDKs from OpenAPI:openapi-generator and Swagger Codegen.

Linting


_10
~/acme-sdks
_10
❯ konfig lint api.yaml
_10
_10
/Users/dylanhuang/Git/konfig/customers/acme/acme-sdks/api.yaml
_10
48:20 warning operationId-pattern Does not match regex: "/^[a-zA-Z0-9]+\_[a-zA-Z0-9]+$/g". Prefix operation IDs with "Tag_" (https://docs.konfigthis.com/tutorials/naming-operation-ids) paths./pet.post.operationId
_10
72:20 warning operationId-pattern Does not match regex: "/^[a-zA-Z0-9]+\_[a-zA-Z0-9]+$/g". Prefix operation IDs with "Tag*" (https://docs.konfigthis.com/tutorials/naming-operation-ids) paths./pet.put.operationId
_10
101:20 warning operationId-pattern Does not match regex: "/^[a-zA-Z0-9]+\_[a-zA-Z0-9]+$/g". Prefix operation IDs with "Tag*" (https://docs.konfigthis.com/tutorials/naming-operation-ids) paths./pet/findByStatus.get.operationId

Example output of Konfig's Linter catching errors regarding Operation IDs

Code generators are garbage in, garbage out.

So if you provide a generator (even ours) with an OpenAPI specification that is low-quality, its impossible for any tool to guarantee a high quality output.

To solve this, Konfig provides you a hand-crafted linter specifically designed to ensure that you always produce high quality SDKs. When using the open source solution you are on your own to ensure that your OpenAPI specification is high-quality. This can take weeks of continuous engineering time to get right.

Higher Quality Output

The Open Source library that we mentioned above does a great job of supporting many languages and frameworks, but it does not provide the same level of quality as Konfig. When publishing SDKs for your customers to write code against, quality is paramount. Lets take a look at a comparison in between the Open Source library and Konfig.

Example Snippet Comparison

To compare the quality of the output, we will look at a snippet of code from the Python SDK generated by the Open Source library and Konfig.

First, lets examine a snippet that makes a simple API call using a Python SDK generated by the Open Source library. Note that this snippet is automatically generated and placed in the README.md of the Python SDK under a section called "Getting Started".

The first thing to notice here is there are 43 lines to make a simple request.


_43
import time
_43
import splitit_client
_43
from pprint import pprint
_43
from splitit_client.api import installment_plan_api
_43
from splitit_client.model.failed_response import FailedResponse
_43
from splitit_client.model.installment_plan_cancel_response import InstallmentPlanCancelResponse
_43
from splitit_client.model.installment_plan_create_request import InstallmentPlanCreateRequest
_43
from splitit_client.model.installment_plan_get_response import InstallmentPlanGetResponse
_43
from splitit_client.model.installment_plan_model import InstallmentPlanModel
_43
from splitit_client.model.installment_plan_refund_request import InstallmentPlanRefundRequest
_43
from splitit_client.model.installment_plan_refund_response import InstallmentPlanRefundResponse
_43
from splitit_client.model.installment_plan_update_request_by_identifier import InstallmentPlanUpdateRequestByIdentifier
_43
from splitit_client.model.installment_plan_update_response import InstallmentPlanUpdateResponse
_43
from splitit_client.model.plan_error_response import PlanErrorResponse
_43
from splitit_client.model.update_order_request import UpdateOrderRequest
_43
from splitit_client.model.verify_authorization_response import VerifyAuthorizationResponse
_43
# The client must configure the authentication and authorization parameters
_43
# in accordance with the API server security policy.
_43
# Examples for each auth method are provided below, use the example that
_43
# satisfies your auth use case.
_43
client_id = os.environ["CLIENT_ID"]
_43
client_secret = os.environ["CLIENT_SECRET"]
_43
configuration = splitit_client.Configuration(
_43
# Defining the host is optional and defaults to https://web-api-v3.sandbox.splitit.com
_43
# See configuration.py for a list of all supported configuration parameters.
_43
host = 'https://web-api-v3.sandbox.splitit.com'
_43
client_id=client_id,
_43
client_secret=client_secret
_43
)
_43
_43
_43
# Enter a context with an instance of the API client
_43
with splitit_client.ApiClient(configuration) as api_client:
_43
# Create an instance of the API class
_43
api_instance = installment_plan_api.InstallmentPlanApi(api_client)
_43
installment_plan_number = "installmentPlanNumber_example" # str |
_43
x_splitit_idempotency_key = "X-Splitit-IdempotencyKey_example" # str |
_43
_43
try:
_43
api_response = api_instance.cancel(installment_plan_number, x_splitit_idempotency_key)
_43
pprint(api_response)
_43
except splitit_client.ApiException as e:
_43
print("Exception when calling InstallmentPlanApi->cancel: %s\n" % e)

16 are dedicated to imports, some of which are not even used.


_43
import time
_43
import splitit_client
_43
from pprint import pprint
_43
from splitit_client.api import installment_plan_api
_43
from splitit_client.model.failed_response import FailedResponse
_43
from splitit_client.model.installment_plan_cancel_response import InstallmentPlanCancelResponse
_43
from splitit_client.model.installment_plan_create_request import InstallmentPlanCreateRequest
_43
from splitit_client.model.installment_plan_get_response import InstallmentPlanGetResponse
_43
from splitit_client.model.installment_plan_model import InstallmentPlanModel
_43
from splitit_client.model.installment_plan_refund_request import InstallmentPlanRefundRequest
_43
from splitit_client.model.installment_plan_refund_response import InstallmentPlanRefundResponse
_43
from splitit_client.model.installment_plan_update_request_by_identifier import InstallmentPlanUpdateRequestByIdentifier
_43
from splitit_client.model.installment_plan_update_response import InstallmentPlanUpdateResponse
_43
from splitit_client.model.plan_error_response import PlanErrorResponse
_43
from splitit_client.model.update_order_request import UpdateOrderRequest
_43
from splitit_client.model.verify_authorization_response import VerifyAuthorizationResponse
_43
# The client must configure the authentication and authorization parameters
_43
# in accordance with the API server security policy.
_43
# Examples for each auth method are provided below, use the example that
_43
# satisfies your auth use case.
_43
client_id = os.environ["CLIENT_ID"]
_43
client_secret = os.environ["CLIENT_SECRET"]
_43
configuration = splitit_client.Configuration(
_43
# Defining the host is optional and defaults to https://web-api-v3.sandbox.splitit.com
_43
# See configuration.py for a list of all supported configuration parameters.
_43
host = 'https://web-api-v3.sandbox.splitit.com'
_43
client_id=client_id,
_43
client_secret=client_secret
_43
)
_43
_43
_43
# Enter a context with an instance of the API client
_43
with splitit_client.ApiClient(configuration) as api_client:
_43
# Create an instance of the API class
_43
api_instance = installment_plan_api.InstallmentPlanApi(api_client)
_43
installment_plan_number = "installmentPlanNumber_example" # str |
_43
x_splitit_idempotency_key = "X-Splitit-IdempotencyKey_example" # str |
_43
_43
try:
_43
api_response = api_instance.cancel(installment_plan_number, x_splitit_idempotency_key)
_43
pprint(api_response)
_43
except splitit_client.ApiException as e:
_43
print("Exception when calling InstallmentPlanApi->cancel: %s\n" % e)

12 are dedicated to instantiating a Configuration object.


_43
import time
_43
import splitit_client
_43
from pprint import pprint
_43
from splitit_client.api import installment_plan_api
_43
from splitit_client.model.failed_response import FailedResponse
_43
from splitit_client.model.installment_plan_cancel_response import InstallmentPlanCancelResponse
_43
from splitit_client.model.installment_plan_create_request import InstallmentPlanCreateRequest
_43
from splitit_client.model.installment_plan_get_response import InstallmentPlanGetResponse
_43
from splitit_client.model.installment_plan_model import InstallmentPlanModel
_43
from splitit_client.model.installment_plan_refund_request import InstallmentPlanRefundRequest
_43
from splitit_client.model.installment_plan_refund_response import InstallmentPlanRefundResponse
_43
from splitit_client.model.installment_plan_update_request_by_identifier import InstallmentPlanUpdateRequestByIdentifier
_43
from splitit_client.model.installment_plan_update_response import InstallmentPlanUpdateResponse
_43
from splitit_client.model.plan_error_response import PlanErrorResponse
_43
from splitit_client.model.update_order_request import UpdateOrderRequest
_43
from splitit_client.model.verify_authorization_response import VerifyAuthorizationResponse
_43
# The client must configure the authentication and authorization parameters
_43
# in accordance with the API server security policy.
_43
# Examples for each auth method are provided below, use the example that
_43
# satisfies your auth use case.
_43
client_id = os.environ["CLIENT_ID"]
_43
client_secret = os.environ["CLIENT_SECRET"]
_43
configuration = splitit_client.Configuration(
_43
# Defining the host is optional and defaults to https://web-api-v3.sandbox.splitit.com
_43
# See configuration.py for a list of all supported configuration parameters.
_43
host = 'https://web-api-v3.sandbox.splitit.com'
_43
client_id=client_id,
_43
client_secret=client_secret
_43
)
_43
_43
_43
# Enter a context with an instance of the API client
_43
with splitit_client.ApiClient(configuration) as api_client:
_43
# Create an instance of the API class
_43
api_instance = installment_plan_api.InstallmentPlanApi(api_client)
_43
installment_plan_number = "installmentPlanNumber_example" # str |
_43
x_splitit_idempotency_key = "X-Splitit-IdempotencyKey_example" # str |
_43
_43
try:
_43
api_response = api_instance.cancel(installment_plan_number, x_splitit_idempotency_key)
_43
pprint(api_response)
_43
except splitit_client.ApiException as e:
_43
print("Exception when calling InstallmentPlanApi->cancel: %s\n" % e)

10 are dedicated to instantiating an ApiClient object and making the API call.


_43
import time
_43
import splitit_client
_43
from pprint import pprint
_43
from splitit_client.api import installment_plan_api
_43
from splitit_client.model.failed_response import FailedResponse
_43
from splitit_client.model.installment_plan_cancel_response import InstallmentPlanCancelResponse
_43
from splitit_client.model.installment_plan_create_request import InstallmentPlanCreateRequest
_43
from splitit_client.model.installment_plan_get_response import InstallmentPlanGetResponse
_43
from splitit_client.model.installment_plan_model import InstallmentPlanModel
_43
from splitit_client.model.installment_plan_refund_request import InstallmentPlanRefundRequest
_43
from splitit_client.model.installment_plan_refund_response import InstallmentPlanRefundResponse
_43
from splitit_client.model.installment_plan_update_request_by_identifier import InstallmentPlanUpdateRequestByIdentifier
_43
from splitit_client.model.installment_plan_update_response import InstallmentPlanUpdateResponse
_43
from splitit_client.model.plan_error_response import PlanErrorResponse
_43
from splitit_client.model.update_order_request import UpdateOrderRequest
_43
from splitit_client.model.verify_authorization_response import VerifyAuthorizationResponse
_43
# The client must configure the authentication and authorization parameters
_43
# in accordance with the API server security policy.
_43
# Examples for each auth method are provided below, use the example that
_43
# satisfies your auth use case.
_43
client_id = os.environ["CLIENT_ID"]
_43
client_secret = os.environ["CLIENT_SECRET"]
_43
configuration = splitit_client.Configuration(
_43
# Defining the host is optional and defaults to https://web-api-v3.sandbox.splitit.com
_43
# See configuration.py for a list of all supported configuration parameters.
_43
host = 'https://web-api-v3.sandbox.splitit.com'
_43
client_id=client_id,
_43
client_secret=client_secret
_43
)
_43
_43
_43
# Enter a context with an instance of the API client
_43
with splitit_client.ApiClient(configuration) as api_client:
_43
# Create an instance of the API class
_43
api_instance = installment_plan_api.InstallmentPlanApi(api_client)
_43
installment_plan_number = "installmentPlanNumber_example" # str |
_43
x_splitit_idempotency_key = "X-Splitit-IdempotencyKey_example" # str |
_43
_43
try:
_43
api_response = api_instance.cancel(installment_plan_number, x_splitit_idempotency_key)
_43
pprint(api_response)
_43
except splitit_client.ApiException as e:
_43
print("Exception when calling InstallmentPlanApi->cancel: %s\n" % e)

In particular, the code for calling an API is redundant and non-ergonomic.

  1. This is redundant.

installment_plan_api.InstallmentPlanApi(api_client)

  1. This is not ergonomic.

api_response = api_instance.cancel(installment_plan_number, x_splitit_idempotency_key)


_43
import time
_43
import splitit_client
_43
from pprint import pprint
_43
from splitit_client.api import installment_plan_api
_43
from splitit_client.model.failed_response import FailedResponse
_43
from splitit_client.model.installment_plan_cancel_response import InstallmentPlanCancelResponse
_43
from splitit_client.model.installment_plan_create_request import InstallmentPlanCreateRequest
_43
from splitit_client.model.installment_plan_get_response import InstallmentPlanGetResponse
_43
from splitit_client.model.installment_plan_model import InstallmentPlanModel
_43
from splitit_client.model.installment_plan_refund_request import InstallmentPlanRefundRequest
_43
from splitit_client.model.installment_plan_refund_response import InstallmentPlanRefundResponse
_43
from splitit_client.model.installment_plan_update_request_by_identifier import InstallmentPlanUpdateRequestByIdentifier
_43
from splitit_client.model.installment_plan_update_response import InstallmentPlanUpdateResponse
_43
from splitit_client.model.plan_error_response import PlanErrorResponse
_43
from splitit_client.model.update_order_request import UpdateOrderRequest
_43
from splitit_client.model.verify_authorization_response import VerifyAuthorizationResponse
_43
# The client must configure the authentication and authorization parameters
_43
# in accordance with the API server security policy.
_43
# Examples for each auth method are provided below, use the example that
_43
# satisfies your auth use case.
_43
client_id = os.environ["CLIENT_ID"]
_43
client_secret = os.environ["CLIENT_SECRET"]
_43
configuration = splitit_client.Configuration(
_43
# Defining the host is optional and defaults to https://web-api-v3.sandbox.splitit.com
_43
# See configuration.py for a list of all supported configuration parameters.
_43
host = 'https://web-api-v3.sandbox.splitit.com'
_43
client_id=client_id,
_43
client_secret=client_secret
_43
)
_43
_43
_43
# Enter a context with an instance of the API client
_43
with splitit_client.ApiClient(configuration) as api_client:
_43
# Create an instance of the API class
_43
api_instance = installment_plan_api.InstallmentPlanApi(api_client)
_43
installment_plan_number = "installmentPlanNumber_example" # str |
_43
x_splitit_idempotency_key = "X-Splitit-IdempotencyKey_example" # str |
_43
_43
try:
_43
api_response = api_instance.cancel(installment_plan_number, x_splitit_idempotency_key)
_43
pprint(api_response)
_43
except splitit_client.ApiException as e:
_43
print("Exception when calling InstallmentPlanApi->cancel: %s\n" % e)

With Konfig, you can delete out all of the unnecessary code and get right to the point of instantiating the SDK and making the API call.

In total, using Konfig only takes 17 lines of code 🤩.


_17
from splitit_client import Splitit
_17
_17
splitit = Splitit(
_17
# Defining the host is optional and defaults to https://web-api-v3.production.splitit.com
_17
# See configuration.py for a list of all supported configuration parameters.
_17
host="https://web-api-v3.production.splitit.com",
_17
# Configure OAuth2 access token for authorization: oauth
_17
client_id="YOUR_CLIENT_ID",
_17
client_secret="YOUR_CLIENT_SECRET",
_17
)
_17
_17
cancel_response = splitit.installment_plan.cancel(
_17
installment_plan_number="installmentPlanNumber_example", # required
_17
x_splitit_idempotency_key="X-Splitit-IdempotencyKey_example", # required
_17
x_splitit_touch_point="", # required
_17
)
_17
print(cancel_response)

There is no need for a long list of imports. Just import the ergonomically named SDK.


_17
from splitit_client import Splitit
_17
_17
splitit = Splitit(
_17
# Defining the host is optional and defaults to https://web-api-v3.production.splitit.com
_17
# See configuration.py for a list of all supported configuration parameters.
_17
host="https://web-api-v3.production.splitit.com",
_17
# Configure OAuth2 access token for authorization: oauth
_17
client_id="YOUR_CLIENT_ID",
_17
client_secret="YOUR_CLIENT_SECRET",
_17
)
_17
_17
cancel_response = splitit.installment_plan.cancel(
_17
installment_plan_number="installmentPlanNumber_example", # required
_17
x_splitit_idempotency_key="X-Splitit-IdempotencyKey_example", # required
_17
x_splitit_touch_point="", # required
_17
)
_17
print(cancel_response)

No need for instantiating a Configuration or ApiClient object. Just instantiate SDK directly.


_17
from splitit_client import Splitit
_17
_17
splitit = Splitit(
_17
# Defining the host is optional and defaults to https://web-api-v3.production.splitit.com
_17
# See configuration.py for a list of all supported configuration parameters.
_17
host="https://web-api-v3.production.splitit.com",
_17
# Configure OAuth2 access token for authorization: oauth
_17
client_id="YOUR_CLIENT_ID",
_17
client_secret="YOUR_CLIENT_SECRET",
_17
)
_17
_17
cancel_response = splitit.installment_plan.cancel(
_17
installment_plan_number="installmentPlanNumber_example", # required
_17
x_splitit_idempotency_key="X-Splitit-IdempotencyKey_example", # required
_17
x_splitit_touch_point="", # required
_17
)
_17
print(cancel_response)

Making the API call is ergonomic and easy to read.


_17
from splitit_client import Splitit
_17
_17
splitit = Splitit(
_17
# Defining the host is optional and defaults to https://web-api-v3.production.splitit.com
_17
# See configuration.py for a list of all supported configuration parameters.
_17
host="https://web-api-v3.production.splitit.com",
_17
# Configure OAuth2 access token for authorization: oauth
_17
client_id="YOUR_CLIENT_ID",
_17
client_secret="YOUR_CLIENT_SECRET",
_17
)
_17
_17
cancel_response = splitit.installment_plan.cancel(
_17
installment_plan_number="installmentPlanNumber_example", # required
_17
x_splitit_idempotency_key="X-Splitit-IdempotencyKey_example", # required
_17
x_splitit_touch_point="", # required
_17
)
_17
print(cancel_response)

First, lets examine a snippet that makes a simple API call using a Python SDK generated by the Open Source library. Note that this snippet is automatically generated and placed in the README.md of the Python SDK under a section called "Getting Started".

The first thing to notice here is there are 43 lines to make a simple request.

16 are dedicated to imports, some of which are not even used.

12 are dedicated to instantiating a Configuration object.

10 are dedicated to instantiating an ApiClient object and making the API call.

In particular, the code for calling an API is redundant and non-ergonomic.

  1. This is redundant.

installment_plan_api.InstallmentPlanApi(api_client)

  1. This is not ergonomic.

api_response = api_instance.cancel(installment_plan_number, x_splitit_idempotency_key)

With Konfig, you can delete out all of the unnecessary code and get right to the point of instantiating the SDK and making the API call.

In total, using Konfig only takes 17 lines of code 🤩.

There is no need for a long list of imports. Just import the ergonomically named SDK.

No need for instantiating a Configuration or ApiClient object. Just instantiate SDK directly.

Making the API call is ergonomic and easy to read.


_43
import time
_43
import splitit_client
_43
from pprint import pprint
_43
from splitit_client.api import installment_plan_api
_43
from splitit_client.model.failed_response import FailedResponse
_43
from splitit_client.model.installment_plan_cancel_response import InstallmentPlanCancelResponse
_43
from splitit_client.model.installment_plan_create_request import InstallmentPlanCreateRequest
_43
from splitit_client.model.installment_plan_get_response import InstallmentPlanGetResponse
_43
from splitit_client.model.installment_plan_model import InstallmentPlanModel
_43
from splitit_client.model.installment_plan_refund_request import InstallmentPlanRefundRequest
_43
from splitit_client.model.installment_plan_refund_response import InstallmentPlanRefundResponse
_43
from splitit_client.model.installment_plan_update_request_by_identifier import InstallmentPlanUpdateRequestByIdentifier
_43
from splitit_client.model.installment_plan_update_response import InstallmentPlanUpdateResponse
_43
from splitit_client.model.plan_error_response import PlanErrorResponse
_43
from splitit_client.model.update_order_request import UpdateOrderRequest
_43
from splitit_client.model.verify_authorization_response import VerifyAuthorizationResponse
_43
# The client must configure the authentication and authorization parameters
_43
# in accordance with the API server security policy.
_43
# Examples for each auth method are provided below, use the example that
_43
# satisfies your auth use case.
_43
client_id = os.environ["CLIENT_ID"]
_43
client_secret = os.environ["CLIENT_SECRET"]
_43
configuration = splitit_client.Configuration(
_43
# Defining the host is optional and defaults to https://web-api-v3.sandbox.splitit.com
_43
# See configuration.py for a list of all supported configuration parameters.
_43
host = 'https://web-api-v3.sandbox.splitit.com'
_43
client_id=client_id,
_43
client_secret=client_secret
_43
)
_43
_43
_43
# Enter a context with an instance of the API client
_43
with splitit_client.ApiClient(configuration) as api_client:
_43
# Create an instance of the API class
_43
api_instance = installment_plan_api.InstallmentPlanApi(api_client)
_43
installment_plan_number = "installmentPlanNumber_example" # str |
_43
x_splitit_idempotency_key = "X-Splitit-IdempotencyKey_example" # str |
_43
_43
try:
_43
api_response = api_instance.cancel(installment_plan_number, x_splitit_idempotency_key)
_43
pprint(api_response)
_43
except splitit_client.ApiException as e:
_43
print("Exception when calling InstallmentPlanApi->cancel: %s\n" % e)

Automation

Konfig's SDK Automation Framework
GitHub Actions UI for a workflow that automates the regeneration of SDKs

Once you've generated your SDKs, you need to publish them to your customers. For every API update, you need to regenerate the SDKs and publish them again. The open source solution is only a generator, not an automation framework. This means that you are on your own to figure out how to automate the process of generating and publishing SDKs. This can take months of engineering time to get right.

Konfig is a full SDK automation framework. This means that you can automate the entire process of generating and publishing SDKs. This includes:

  1. Testing
  2. Versioning & Publishing
  3. Manual & Automated updates
  4. GitHub Actions
  5. Submodule Support
  6. Polling
  7. Breaking Change Detection
  8. Linting in CI

To build the tooling that can do all of this would take months of engineering time. With Konfig, you can get started in minutes.

The Impact of Konfig on Your Business

Now that you have an understanding of the advantages of using Konfig for your customers, let's discuss the impact on the dollars and cents of your business. From a cost savings perspective, it's no secret that engineers are very expensive and SDKs are hard and time consuming to create. Even large companies like Twilio are devoting 2 or more engineer's time to update their SDKs after every API update, so by using Konfig, you can save on the cost of 1 or 2 full time engineers or roughly a $200k+ per year annual cost saving.

From a revenue generation perspective, easier onboarding with SDKs in all major languages means more customers can evaluate your product and if they buy, they can integrate your API and start paying you faster. While the exact dollar amount of revenue gained by using Konfig depends on your contract size, our case study with SnapTrade shows how they were able to double the number of prospects evaluating their product, increase customer conversion of those prospects, and significantly reduce onboarding time by using Konfig.

Any way you look at it, the ROI of using Konfig is significant. If you are interested in learning more, you can check out our documentation or book a demo with us. We would love to hear from you!

Please book a demo with us to learn more about how Konfig can help your business. If you are interested in learning more about Konfig, check out our documentation.

Our Docs Product

Our Docs product also natively integrates with Konfig's SDKs to build a seamless end-to-end developer experience. You can learn more about Docs here.

Dylan Huang
Dylan HuangGitHubLinkedIn

Dylan is a Co-Founder at Konfig. Previously, he built SDK & API tooling at C3.ai. He also once built a viral website with over 210,000 unique users.

Anh-Tuan Bui
Anh-Tuan BuiLinkedIn

Anh-Tuan is a Co-Founder at Konfig. Previously, he Co-Founded TAI, an investment app that helped people learn about and trade ETFs. There, he went through the pain of integrating with APIs and wants to help other startups avoid the same issue.