Освободите руки и изящно вызывайте интерфейс бэкенда💗

внешний интерфейс JavaScript
Освободите руки и изящно вызывайте интерфейс бэкенда💗

«Я второй день участвую в ноябрьских челленджах, подробности мероприятия Посмотреть:Вызов последнего обновления 2021 г."

Всем привет, я Frozen Fish🐟, фронтенд водной системы💦, люблю прибамбасы💐, и продолжаю лепить из песка🌲. Я хороший брат Hancao🌿 по соседству, и я только начал писать статьи. Если вам понравилась моя статья, вы можете подписаться➕Нравится, влить в меня энергию и расти вместе со мной~

Прочтите эту статью 🦀

1. Как автоматически генерировать модули API на основе TypeScript

2. Как развязать руки бизнес-одноклассникам и позволить им больше сосредоточиться на реализации бизнеса

3. Вы узнаете, что такое Swagger, OpenAPI,StopLight

4. Вы научитесь быстро и удовлетворительно выполнять задачу, когда сталкиваетесь с совершенно нетронутым спросом

5. Как писать инструменты CLI для автоматизации операций

Предисловие 🌵

Вы пишете интерфейсМодуль запроса APIкогда,Напишите внешний интерфейс запроса, читая документацию.Шерстяная ткань? писать разныеTS дженерики,определение типа, Привести кНеэффективное развитие, при изменении внутреннего интерфейса необходиморуководствомодифицироватьинтерфейс запроса🕶

Как решить такие инженерные задачи? Мы можем воспользоваться преимуществом определения интерфейсаСтандартная документация API, который автоматически генерирует внешний интерфейс на основеTypeScriptизМодуль вызова API, чтобы мы могли начать развивать бизнес напрямую, не читая документацию по интерфейсу API, давайте посмотрим на это вместе~

Предварительное знание 🐳

  • OpenAPI

    Человеческие слова — это спецификация, определяющая API

    Спецификация OpenAPI — это стандартный формат для определения структуры и синтаксиса REST API. Документация OpenAPI удобна для чтения машиной и человеком, что позволяет любому легко определить, как работает каждый API. Инженеры, создающие API-интерфейсы, могут использовать API-интерфейсы для планирования и проектирования серверов, создания кода и реализации контрактных тестов.

  • Swagger

    img

    Инструмент для генерации интерфейсных документов согласно спецификации OpenAPI.

    Swagger — это имя, связанное с некоторыми из самых известных и широко используемых инструментов для реализации спецификации OpenAPI. Набор инструментов Swagger включает в себя комбинацию бесплатных и коммерческих инструментов с открытым исходным кодом, которые можно использовать на разных этапах жизненного цикла API.

  • StopLight

    Stoplight Reviews 2021: Details, Pricing, & Features | G2

    Люди говорят, что StopLight такой же инструмент как и Swagger для генерации интерфейсных документов по спецификации OpenAPI.Его нужно платить.Короче,сильнее и лучше в использовании~~

    stopLight — это прежде всего инструмент управления дизайном API, который может использовать отраслевые стандарты, такие как OpenAPI, для проектирования, разработки, тестирования и документирования HTTP API, а также Markdown для документирования письменных форм.

  • Файл спецификации API

image-20211031000240795

Четкие потребности 🐿

  • Напишите инструмент командной строки, чтобы внешнему интерфейсу нужно было выполнить только строку команд для создания готовых модулей запросов API.
  • Получите файл спецификации StopLight в формате YML или JSON.
  • Создавайте модули запросов API в папке node_modules в соответствии с текстовым файлом, интегрируйте сгенерированные файлы и экспортируйте их единообразно.
  • Вы можете создавать различные версии модулей запросов API в соответствии с файлом конфигурации.
  • Должен быть совместим со спецификациями Swagger2.0 и OpenAPI3.0.
  • Напишите документ README проекта

Удовлетворяйте потребности 🐰

Изучите основные функции

Основная функция заключается в том, как генерировать модули API на основе TypeScript?

Можно автоматически написать шаблонизатор для генерации кода, но это слишком большая нагрузка, а моего уровня недостаточно, поэтому я полагаюсь только на сторонние библиотеки.

Благодаря большому доступу к Github и материалам, суммированы следующие решения.

1. Используйте официальный Swagger-codegen

GitHub.com/swagger-API…

Либо инструмент генерации представляет собой пакет JAR, либо файл библиотеки, написанный на JS, давно не поддерживается, так что сдавайтесь.

2.free-swagger

GitHub.com/shale1996/post…

Написано китайцем, но количество стартов маловато, сгенерированный тип кода теряется по любому, сдавайтесь

3.ts-gear

GitHub.com/супер не может/одновременно-…

Он был написан г-ном Мо из Jingdong, но при моем использовании я обнаружил, что поддержка OpenAPI3 не очень хороша, поэтому я отказался

4.swagger-typescript-api

GitHub.com/код ACA/чулки…

Написанный иностранными друзьями, этот проект имеет более 600 запусков, и код генерируется с использованием шаблонов, но документация написана плохо, но эффект от реализации неплох.Наконец, эта библиотека используется, но наступил на много ям

Написать файл ввода CLI 🍓

назначенный вход

package.json

{
  //...
  "bin": {
    "heimdall": "bin/heimdall.js"
  }
 //...
}

Вытяните файл спецификации 🍎

StopLightДокументация по интерфейсу API будет размещена вGithub, поэтому нам нужно реализовать файл спецификации pull в CLI.

Часть кода опущена ниже

//...

//初始化命令行帮助信息,并获取命令行参数

const options = getCommandOptions()

//生成API入口
if (options.generate) {
    const projectName = getProjectName()
    //1.执行下载文件命令
    await gitCloneProject(projectName)
    //2.生成api文件
    //2.1删除之前下载过的API文件
    await removeDir(path.resolve(cwd(), "node_modules/@imf/heimdall-ts/api"))

    await createApi()
    //3.生成入口文件
    await generateMain()
    //4.删除下载的yml所在文件夹
    await removeDir(path.resolve(cwd(), getProjectName()))

} else if (options.log) {
    const projectName = getProjectName()
    //1.执行下载文件命令
    await gitCloneProject(projectName, true)
    //2.执行打印日志的命令
    await showLog()
    //3.删除下载的文件夹
    await removeDir(path.resolve(cwd(), getProjectName()))
}

//...


/**
 * 克隆项目
 */
function gitCloneProject(projectName, isLog = false) {
    return new Promise<void>((resolve, reject) => {
        shell.exec(`git clone https://sudongyu:YUANCxzeJwiVhzQio18v@git.stoplight.io/floozy/${projectName}.git`, {
            cwd: `${cwd()}`
        }, () => {
            const versionCode = getPkgMaifest()?.heimdall?.versionCode
            //如果有versionCode,需要回退版本
            if (!isLog && versionCode) {
                shell.exec(`git checkout ${versionCode}`, {
                    cwd: `${path.resolve(cwd(), getProjectName())}`
                }, () => {
                    resolve()
                })
            } else {
                resolve()
            }
        })
    })
}


Создайте модуль вызова API на основе TS 🍌

использовать swagger-typescript-apiЭта библиотека для создания кода и размещения его в папке node_modules, чтобы он не влиял на структуру каталогов кода потребителя.

/**
 * 创建api文件
 */
 function createApi() {
     return new Promise<void>(async (resolve, reject) => {
         //V3
         /* NOTE: all fields are optional expect one of `output`, `url`, `spec` */
         const openApi3Array = getOenAPI3YmlFileName(path.resolve(cwd(), `${getProjectName()}`))
         for (let item of openApi3Array) {
             await generateApi({
                 name: `${item.replace('.oas3.yml', '')}Api.ts`,
                 url: null,
                 output: path.resolve(process.cwd(), "node_modules/@imf/heimdall-ts/api"),
                 input: path.resolve(process.cwd(), `${getProjectName()}`, `${item}`),
                 httpClientType: "axios", // or "fetch",
                 unwrapResponseData: true,
                 generateUnionEnums: true,
                 enumNamesAsValues: true,
                 moduleNameFirstTag: false,
                 moduleNameIndex:-1
             })
         }

         //V2
         /* NOTE: all fields are optional expect one of `output`, `url`, `spec` */
         const openApi2Array = getOenAPI2YmlFileName(path.resolve(cwd(), `${getProjectName()}`))
         for (let item of openApi2Array) {
             await generateApi({
                 name: `${item.replace('.oas2.yml', '')}Api.ts`,
                 url: null,
                 output: path.resolve(process.cwd(), "node_modules/@imf/heimdall-ts/api"),
                 input: path.resolve(process.cwd(), `${getProjectName()}`, `${item}`),
                 httpClientType: "axios", // or "fetch",
                 unwrapResponseData: true,//是否包裹response
                 generateUnionEnums: true,
                 enumNamesAsValues: true,
                 moduleNameFirstTag: false,
                 moduleNameIndex:-1 //模块名分割
             })
         }
         if(!openApi3Array.length&&!openApi2Array.length){
             await removeDir(path.resolve(cwd(), getProjectName()))
             reject('no openApi3 or openApi2 resources to generate !!!!!')
         }
            resolve()
     })

}

Интегрируйте и экспортируйте 🥝

из-за swagger-typescript-apiФайлы, сгенерированные этой библиотекой, являются отдельными, нам нужно интегрировать сгенерированные файлы и использовать регулярные выражения и строки шаблона для создания файлов входа в библиотеку.

/**
 * 生成入口文件index.ts
 */
function generateMain() {
    return new Promise<void>((resolve, reject)=>{
        //获取文件名
        const fileNames = getFileName(path.resolve(cwd(), 'node_modules/@imf/heimdall-ts/api'))
        //转换文件名 eg:  main.ts -> MainGameApi
        const transformedFileNames = fileNames.map(item => {
            return transformToCamel(item)
        })
        //编写要写如的内容content
        const content = `
        ${transformedFileNames.map((item, index) => {
                return `import \{Api as ${item}\} from \'\.\/${fileNames[index]}\'\n`
            }).join('')
        }
   
   export {
        ${transformedFileNames.map(item => {
            return `${item}\n`
        })}
    }
   `
        //创建index文件
        generateFile(path.resolve(cwd(),'node_modules/@imf/heimdall-ts/api','index.ts'))
        //写入文件
        writeFile(path.resolve(cwd(),'node_modules/@imf/heimdall-ts/api','index.ts'),content).then(()=>{
            resolve()
        })
    })
}

Поддержка резервной версии 🍉

Изначально реализованы базовые функции, но босс выдвинул новое требование, в котором нужно поддерживать откат версии, чтобы звонилка могла легко управлять своими модулями API

  • Чтобы просмотреть номер версии документа API, мое решение здесь состоит в том, чтобы использовать команду инструмента управления версиями git для просмотра журнала для достижения

    /**
     * 打印版本stoplight版本信息
     */
    function showLog(){
        return new Promise<void>((resolve, reject)=>{
            shell.exec('git log --pretty=" %h %ci %s "', {
                    cwd: `${path.resolve(cwd(), getProjectName())}`
                },()=>{
                resolve()
                }
            )
        })
    }
    
  • Выполните команду git checkout, чтобы переключиться на соответствующую версию хранилища, а затем сгенерируйте модуль API в соответствии с этим документом, тем самым реализуя откат версии.

    function gitCloneProject(projectName, isLog = false) {
        return new Promise<void>((resolve, reject) => {
            shell.exec(`git clone https://sudongyu:YUANCxzeJwiVhzQio18v@git.stoplight.io/floozy/${projectName}.git`, {
                cwd: `${cwd()}`
            }, () => {
                const versionCode = getPkgMaifest()?.heimdall?.versionCode
                //如果有versionCode,需要回退版本
                if (!isLog && versionCode) {
                    shell.exec(`git checkout ${versionCode}`, {
                        cwd: `${path.resolve(cwd(), getProjectName())}`
                    }, () => {
                        resolve()
                    })
                } else {
                    resolve()
                }
            })
        })
    

Пишите документацию 📃

После того, как написана логика кода библиотеки, самое главное написать документацию😁, написать красивую и понятную документацию, библиотека готова.

image-20211031143811243

Отображение эффекта проекта 🪖

  • гиф-шоу

    auth-example

  • автоматически сгенерированный код

    image-20211031000538089

  • Импорт API для использования из автоматически созданной библиотеки модулей API (умные подсказки)

    image-20211031000700511

  • Отправить запрос с помощью модуля API

    Из-за сгенерированного TS есть очень хорошие подсказки по коду, и вы можете напрямую указать интерфейс, который хотите вызвать.

image-20211031001059973

Все данные имеют соответствующие типы TS

image-20211031001201062

Урожай 🍁

Самая большая выгода от написания этой библиотеки состоит в том, что мы столкнулись с совершенно неизвестным требованием, а что, если мы решим эту проблему? Что делать, если используемая сторонняя библиотека не соответствует вашим потребностям. То, что я узнал, является первымпо результатам, проясните свои идеи и реализуйте каждую шаг за шагом. Если вы столкнетесь с препятствиями, перейдите к просмотру дополнительных сторонних библиотек.GithubВверхвыпускать или читать исходный код, может быть хорошим решением проблемы. Конечно же, я также научился элегантно вызывать внутренний интерфейс, чтобы помочь студентам-бизнесменам повысить эффективность разработки 😂~

Вывод 🌞

img

тогда мой释放双手,优雅地调用后端接口💗На этом статья окончена.Цель статьи на самом деле очень простая, то есть для повседневной работы.总结和输出, выведите то, что, по вашему мнению, будет полезно всем,Не важно, готовишь ты или нет, но люби🔥, надеемся встретить больше друзей-единомышленников через статью, если вам тоже нравится折腾, добро пожаловать, чтобы добавить меня好友,Вместе沙雕,Вместе进步.

гитхаб🤖:sudongyu

Личный блог 👨‍💻:блог о замороженной рыбе

vx👦:судонгюэр

写在最后

Друзья, если вам нравится мой口水话Ставьте 🐟🐟 лайк👍 или подписывайтесь➕ это самая большая поддержка для меня.

добавь меня в WeChat:sudongyuer, приглашаем вас присоединиться к группе, вместе изучить интерфейс и стать лучшим инженером~ (QR-код группы находится здесь ->Ложитесь спать рано,Если срок действия QR-кода истек, посмотрите комментарии в точке кипения ссылки.Я размещу последний QR-код в области комментариев.Конечно, вы также можете добавить меня в WeChat и я притяну вас в группу.После все, я тоже интересный фронтенд, и меня не плохо знать 🌟 ~