using oasdiff to detect breaking

چگونه از oasdiff برای شناسایی تغییرات مخرب در APIها استفاده می‌شود؟

نسخه‌بندی API به طور فزاینده‌ای رایج شده است، و نه فقط برای APIهای بسیار محبوب یا تجاری. حتی APIهای علاقه‌مندی‌های ویژه و تفریحی مانند Sportradar دارای نسخه‌های متعدد هستند. این می‌تواند برای توسعه‌دهندگان و کاربران مشکلاتی ایجاد کند.
نسخه‌بندی تمایل دارد که باعث خرابی شود. کد موجود ممکن است به همراه API به‌روزرسانی نشود. oasdiff، یک ابزار متن‌باز برای شناسایی تغییرات در مشخصات OpenAPI، برای جلوگیری از ایجاد مشکلات برای توسعه‌دهندگان و مشتریان شما ایجاد شده است.

oasdiff می‌تواند به‌عنوان یک بسته Golang یا یک ابزار خط فرمان اجرا شود.

این ابزار مشخصات OpenAPI را معمولاً در قالب JSON یا YAML مقایسه می‌کند و گزارشی ارائه می‌دهد که تفاوت‌ها را برجسته می‌کند. oasdiff همه چیز را از نقاط پایانی تا پارامترهای درخواست/پاسخ برای به‌روزرسانی‌ها و بازبینی‌ها تحلیل می‌کند و به‌ویژه به دنبال تغییراتی است که می‌توانند باعث اختلال در یکپارچه‌سازی‌ها شوند. این یک ابزار بی‌نظیر برای خطوط CI/CD است.

در ادامه، نحوه شروع کار با oasdiff برای جلوگیری از خرابی یا قطع خدمات هنگام به‌روزرسانی API شما نشان داده می‌شود.

۱. نصب oasdiff

گزینه‌های متعددی برای نصب oasdiff در مخزن oasdiff ذکر شده است، از نصب‌کننده‌های macOS، Windows و Linux تا بارگذاری با Go. برای این آموزش، روش Go را استفاده می‌کنیم، زیرا بسته Go امکان ادغام آسان در یک خط CI/CD را فراهم می‌کند.

ابتدا، اگر Go را نصب نکرده‌اید، باید آن را نصب کنید.

پس از نصب Go، دستور زیر را در ترمینال خود وارد کنید.

go install github.com/tufin/oasdiff@latest

توجه داشته باشید که اگر به‌تازگی Go را نصب کرده‌اید و هنگام اجرای این دستور با خطا مواجه شدید، یک نمونه تازه از ترمینال باز کنید که معمولاً مشکل را حل می‌کند.

اگر از macOS استفاده می‌کنید، می‌توانید oasdiff را با Brew نیز نصب کنید:

brew tap tufin/homebrew-tufin
brew install oasdiff

oasdiff Wrappers

oasdiff چندین Wrapper نیز دارد، اگر می‌خواهید بدون نصب چیزی آن را امتحان کنید.

  • GitHub Action

  • Cloud Service

  • OpenAPI Sync

۲. امتحان کردن oasdiff

پس از نصب oasdiff، می‌توانید آن را امتحان کنید تا ببینید چگونه کار می‌کند. ابتدا مطمئن شوید که مخزن GitHub را کلون کرده‌اید. پس از آن، می‌توانید oasdiff diff را اجرا کنید تا تفاوت بین دو فایل YAML محلی را مشاهده کنید.

oasdiff diff data/openapi-test1.yaml data/openapi-test2.yaml

پس از اجرا، خروجی زیر را مشاهده خواهید کرد:

info:
contact:
added: true
version:
from: ۱.۰
to: ۱.۰
...

همان‌طور که مشاهده می‌کنید، خروجی oasdiff جزئیات فوق‌العاده‌ای از تمام بازبینی‌های انجام شده بین دو نسخه ارائه می‌دهد. به عنوان مثال، نقاط پایانی زیر در این مثال حذف شده‌اند: /subscribe، /api/{domain}/{project}/install-command، و /register.

در بخش تغییر یافته، می‌توانید ببینید که نقطه پایانی /api/{domain}/{project}/badges/security-score: یک دستور POST اضافه کرده است. همچنین تعدادی ویژگی منسوخ شده‌اند که در جزئیات ذکر شده‌اند.

می‌توانید نتایج را به صورت HTML نیز نمایش دهید تا لیست مرتب‌تری داشته باشید:

oasdiff diff data/openapi-test1.yaml data/openapi-test2.yaml -f html

oasdiff فقط روی فایل‌های محلی کار نمی‌کند. می‌توانید به همان راحتی تفاوت بین APIهای راه دور را با استفاده از HTTP/s مشاهده کنید.

oasdiff diff https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test1.yaml https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test3.yaml -f text

نتایج نشان می‌دهند که چهار نقطه پایانی تغییر کرده‌اند: security-score، install-command، register و subscribe.

برای مشاهده هرگونه تغییر مخرب بین دو نسخه، از دستور زیر استفاده کنید:

oasdiff breaking https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test1.yaml https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test3.yaml

این نتایج نشان می‌دهند که تغییر وضعیت موفقیت به ۲۰۰ یا ۲۰۱ در نقطه پایانی security-score باعث ایجاد مشکل می‌شود.

حتی یک دستور اختصاصی برای ارزیابی نقاط پایانی با مسیر /API وجود دارد:

oasdiff diff https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test1.yaml https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test3.yaml -f text -p "/api"

می‌توانید نقاط پایانی را نیز مستثنی کنید. می‌توانید نام مسیرها را با استفاده از دستور –match-path فیلتر کنید و مسیرهایی که با یک عبارت خاص مطابقت ندارند را حذف کنید. همچنین می‌توانید پسوندهای خاص را با دستور –filter-extension فیلتر کنید.

۳. ادغام oasdiff در پروژه‌های Go

یکی از بزرگ‌ترین دلایل استفاده از oasdiff، ادغام در یک گردش کار خودکار است. اگر در Go توسعه می‌دهید، می‌توانید از oasdiff مستقیماً در کد خود استفاده کنید. کافیست از دستور زیر استفاده کنید:

diff.Get(&diff.Config{}, spec1, spec2)

نمونه‌ای از استفاده oasdiff در یک برنامه Go:

loader := openapi3.NewLoader()
loader.IsExternalRefsAllowed = true
s1, err := loader.LoadFromFile(“../data/simple1.yaml”)
if err != nil {
fmt.Fprintf(os.Stderr, “failed to load spec with %v”, err)
return
}

s2, err := loader.LoadFromFile(“../data/simple2.yaml”)
if err != nil {
fmt.Fprintf(os.Stderr, “failed to load spec with %v”, err)
return
}

diffReport, err := diff.Get(diff.NewConfig(), s1, s2)

if err != nil {
fmt.Fprintf(os.Stderr, “diff failed with %v”, err)
return
}

bytes, err := yaml.Marshal(diffReport)
if err != nil {
fmt.Fprintf(os.Stderr, “failed to marshal result with %v”, err)
return
}
fmt.Printf(“%s\n”, bytes)

خروجی:

aths:
modified:
/api/test:
operations:
added:
- POST
deleted:
- GET
endpoints:
added:
- method: POST
path: /api/test
deleted:
- method: GET
path: /api/test

همچنین می‌توانید از oasdiff برای شناسایی تغییرات مخرب در داخل کد خود استفاده کنید.

package main

import (
“fmt”
“os”
“strings”

“github.com/getkin/kin-openapi/openapi3”
“github.com/tufin/oasdiff/checker”
“github.com/tufin/oasdiff/diff”
“github.com/tufin/oasdiff/load”
)

func main() {
loader := openapi3.NewLoader()
loader.IsExternalRefsAllowed = true

s1, err := load.LoadSpecInfo(loader, load.NewSource(“../data/openapi-test1.yaml”))
if err != nil {
fmt.Fprintf(os.Stderr, “failed to load spec with %v”, err)
return
}

s2, err := load.LoadSpecInfo(loader, load.NewSource(“../data/openapi-test3.yaml”))
if err != nil {
fmt.Fprintf(os.Stderr, “failed to load spec with %v”, err)
return
}

diffConfig := diff.NewConfig().WithCheckBreaking()

diffRes, operationsSources, err := diff.GetPathsDiff(diffConfig,
[]*load.SpecInfo{s1},
[]*load.SpecInfo{s2},
)

if err != nil {
fmt.Fprintf(os.Stderr, “diff failed with %v”, err)
return
}

errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), diffRes, operationsSources)

errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, “../data/ignore-err-example.txt”, checker.NewDefaultLocalizer())
if err != nil {
fmt.Fprintf(os.Stderr, “ignore errors failed with %v”, err)
return
}

errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.WARN, errs, “../data/ignore-warn-example.txt”, checker.NewDefaultLocalizer())
if err != nil {
fmt.Fprintf(os.Stderr, “ignore warnings failed with %v”, err)
return
}

if len(errs) > ۰ {
localizer := checker.NewDefaultLocalizer()
count := errs.GetLevelCount()
fmt.Print(localizer(“total-errors”, len(errs), count[checker.ERR], “error”, count[checker.WARN], “warning”))
for _, bcerr := range errs {
fmt.Printf(“%s\n\n”, strings.TrimRight(bcerr.SingleLineError(localizer, checker.ColorNever), ” “))
}
}

}

خروجی:

۴ تغییر مخرب: ۱ خطا، ۳ هشدار
خطا در ../data/openapi-test3.yaml، در API GET /api/{domain}/{project}/badges/security-score پاسخ موفقیت با وضعیت '۲۰۱' حذف شد [response-success-status-removed].
هشدار در ../data/openapi-test3.yaml، در API GET /api/{domain}/{project}/badges/security-score پارامتر درخواست ‘cookie’ با نام ‘test’ حذف شد [request-parameter-removed].

هشدار در ../data/openapi-test3.yaml، در API GET /api/{domain}/{project}/badges/security-score پارامتر درخواست ‘header’ با نام ‘user’ حذف شد [request-parameter-removed].

هشدار در ../data/openapi-test3.yaml، در API GET /api/{domain}/{project}/badges/security-score پارامتر درخواست ‘query’ با نام ‘filter’ حذف شد [request-parameter-removed].

جمع‌بندی درباره oasdiff

نسخه‌بندی API تنها با ادامه رشد APIها در صنعت نرم‌افزار رایج‌تر خواهد شد. تشخیص تفاوت بین دو نسخه تنها یکی از کاربردهای بالقوه oasdiff است. توانایی شناسایی تغییرات مخرب، به ویژه قبل از وقوع آن‌ها، دلیل دیگری برای ادغام oasdiff در گردش کار شما است. چند خط کد می‌تواند از قطعی خدمات و توقف غیرمنتظره برای شما و مشتریانتان جلوگیری کند.

مزایای پروتوباف‌ها برای میکروسرویس‌های (Protobufs For Internal Microservices) داخلی چیست؟
چگونه امنیت LLM به امنیت API وابسته است؟

دیدگاهتان را بنویسید

سبد خرید
علاقه‌مندی‌ها
مشاهدات اخیر
دسته بندی ها