首页 > 后端开发 > Golang > 正文

从零到合并:在 Go 中构建 JSON 重命名字段组件

Barbara Streisand
发布: 2024-11-13 15:43:02
原创
482 人浏览过

From Zero to Merge: Building a JSON Renaming Field Component in Go

Introduction to Instill-ai

Working on Instill’s pipeline-backend project was like solving a jigsaw ? puzzle—except some pieces kept changing names! My mission? To create a component that could rename JSON fields without creating conflicts. Join me as I share my journey through learning Go, studying Instill’s well-organized docs, and creating a solution that’s now merged and ready to roll! ?


The Challenge

Instill needed a way to rename fields in JSON data structures dynamically. The twist? We had to handle cases where a renamed field might clash with an existing field. Without a conflict resolution system, chaos would reign supreme!

From Zero to Merge: Building a JSON Renaming Field Component in Go instill-ai / pipeline-backend

⇋ A REST/gRPC server for Instill VDP API service

pipeline-backend

From Zero to Merge: Building a JSON Renaming Field Component in Go

pipeline-backend manages all pipeline resources within Versatile Data Pipeline (VDP) to streamline data from the start component, through AI/Data/Application components and to the end component.

Concepts

Pipeline

In ? Instill VDP, a pipeline is a DAG (Directed Acyclic Graph) consisting of multiple components.

flowchart LR
s[Trigger] --> c1[OpenAI Component]
c1 --> c2[Stability AI Component]
c1 --> c3[MySQL Component]
c1 --> e[Response]
c2 --> e
登录后复制
Loading

Component

A Component serves as an essential building block within a Pipeline.

See the component package documentation for more details.

Recipe

A pipeline recipe specifies how components are configured and how they are interconnected.

Recipes are defined in YAML language:

variable
  <span># pipeline input fields</span>
output:
  <span># pipeline output fields</span>
component:
  <component-id>:
    type: <component-definition-id>
    task: <task-id>
    input:
      <span># values for the input fields</span>
    condition: <condition> <span># conditional statement to execute or bypass the</span>
登录后复制
Enter fullscreen mode Exit fullscreen mode
GitHub에서 보기

To be honest, I was starting to doubt if I could solve this issue, but then Anni dropped the perfect message that kept me going.

From Zero to Merge: Building a JSON Renaming Field Component in Go

Once I got comfortable, ChunHao, who had crafted a JSON schema for this task, gave me the green light? to start coding. And so, the journey began!


Step 2️⃣: Designing the Solution

The key requirements were:

  1. Dynamic Renaming: Fields should be renamed without disturbing the JSON structure.
  2. Conflict Detection: We needed to spot any conflicts between the original and renamed fields.
  3. Conflict Resolution: A smooth solution, like appending a suffix, would prevent name clashes.

From Zero to Merge: Building a JSON Renaming Field Component in Go


Step 3️⃣: Building the Component

Armed with coffee☕ and courage?, I got down to coding. Here’s a sneak peek at the core logic:

Mapping Fields

First, I created a mapping system to track old and new field names. This was key to detecting conflicts.

func mapFields(fields map[string]string) map[string]string {
    newFieldMap := make(map[string]string)
    for oldName, newName := range fields {
        // Check for conflict
        if _, exists := newFieldMap[newName]; exists {
            newName += "_conflict" // Add suffix for conflicts
        }
        newFieldMap[oldName] = newName
    }
    return newFieldMap
}
登录后复制

Any time a conflict was detected, the function added "_conflict" to the new name. It’s a simple trick that ensures our JSON fields stay unique and, most importantly, friendly to each other! ✌️

Renaming Fields

Once the field mappings were in place, the next step was applying them to our JSON data.

func renameFields(data map[string]interface{}, fieldMap map[string]string) map[string]interface{} {
    renamedData := make(map[string]interface{})
    for key, value := range data {
        newKey := fieldMap[key]
        renamedData[newKey] = value
    }
    return renamedData
}
登录后复制

Here’s the logic that applies the mapped names to our JSON data. The result? Our data’s neatly renamed, conflicts resolved, and structure intact. ?

After creating the component dropped the draft PR & got a comment:

From Zero to Merge: Building a JSON Renaming Field Component in Go


Step 4️⃣: Testing and Refinement

After familiarizing myself with Instill's testing methods and learning how to create effective test cases, I proceeded further.

From Zero to Merge: Building a JSON Renaming Field Component in Go

Testing time! ? I wrote tests covering everything from simple renames to complex edge cases with nested JSON fields. Each round of testing led to further refinements.

{
    name: "ok - rename fields with overwrite conflict resolution",
    // Test where renaming conflicts are resolved by overwriting the existing field.
    // Expected outcome: "newField" holds "value1", overwriting any previous value.
},

{
    name: "ok - rename fields with skip conflict resolution",
    // Test where conflicts are resolved by skipping the rename if the target field already exists.
    // Expected outcome: "newField" remains "value2" without overwrite.
},

{
    name: "nok - rename fields with error conflict resolution",
    // Test with "error" strategy, which should raise an error on conflict.
    // Expected outcome: Error message "Field conflict."
},

// Additional cases for missing required fields and invalid conflict resolution strategy
登录后复制

Here’s where I’d love to share a personal reflection: Testing was the hardest part of this project ?‍?. There were times when I thought, "Is this test even doing what it’s supposed to?"

Gerade in diesem Moment stieß ich auf ein Fusselproblem

From Zero to Merge: Building a JSON Renaming Field Component in Go

Er wies auf das Problem hin und lieferte sogar die Lösung. Ich musste es nur implementieren, aber es war eine Erinnerung daran, dass selbst die kleinsten Details wichtig sind, damit der Code reibungslos funktioniert.

Sobald ich diese anfänglichen Hürden überwunden hatte, wurde das Testen zu meinem Sicherheitsnetz. Es gab mir die Gewissheit, dass mein Code in verschiedenen Szenarien funktionieren würde ?️‍♂️. Es hat mir auch gezeigt, dass das Testen nicht nur ein Schritt zum Abhaken ist, sondern eine Möglichkeit, sicherzustellen, dass mein Code zuverlässig und belastbar ist.


Schritt 5️⃣: CI-Prüfung und letzte Anpassungen

Nach Abschluss meiner Tests habe ich meinen Code gepusht, bereit für den Überprüfungsprozess. Unsere CI-Prüfungen (Continuous Integration) bestanden jedoch nicht. Annis Kommentar erinnerte mich sanft daran, meine Testfälle noch einmal zu überprüfen:

„Hey @AkashJana18, könntest du deine Testfälle überprüfen? Unser CI-Check zeigt, dass es hier nicht bestanden wurde. Bitte testen Sie es zuerst lokal, bevor Sie es an die PR weiterleiten. Wann immer Sie Ihren Commit vorantreiben, lösen wir die Prüfungen aus, damit Sie etwaige Probleme erkennen können, bevor unsere Ingenieure Ihren Code überprüfen. Danke!“

From Zero to Merge: Building a JSON Renaming Field Component in Go

Da wurde mir klar, dass ich die Tests vor dem Absenden lokal ausführen musste. ChunHao fügte außerdem hinzu:

"Bitte führen Sie es aus und bestehen Sie es, bevor Sie die Überprüfung anfordern. Führen Sie $ go test ./pkg/component/operator/json/v0/... aus, um es lokal zu überprüfen."

Ich habe die Tests schnell vor Ort durchgeführt, die Probleme identifiziert und behoben.

From Zero to Merge: Building a JSON Renaming Field Component in Go

From Zero to Merge: Building a JSON Renaming Field Component in Go
Ein kleiner Moment des Feierns?

Durch diesen Prozess wurde mir noch mehr bewusst, wie wichtig lokale Tests sind, da dadurch sichergestellt wurde, dass alles solide war, bevor ich es zur Überprüfung einreichte.

Vor der Zusammenführung führte ChunHao eine abschließende Überprüfung durch, nahm ein paar Optimierungen vor, überprüfte das Testrezept und aktualisierte die Dokumentation, um die neuen Änderungen widerzuspiegeln. Vielen Dank an Anni für ihre kontinuierliche Unterstützung während des gesamten Prozesses – es hat einen großen Unterschied gemacht. ?


? Réflexion sur le processus collaboratif ???‍???

L'une des plus grandes leçons que j'ai apprises était de savoir comment la collaboration et le mentorat peuvent faire ou défaire un projet. Les modérateurs d'Instill, Anni et ChunHao, m'ont fourni les conseils dont j'avais besoin lorsque j'étais perdu dans la syntaxe Go ou que j'avais du mal à trouver la bonne approche. En travaillant ensemble, nous avons transformé un problème complexe en une solution propre et fonctionnelle.

Je vais être honnête, il y a eu des moments où j’ai eu l’impression d’avoir mordu plus que je ne pouvais mâcher. Mais les encouragements constants d'Anni, combinés aux instructions claires de ChunHao, m'ont permis de rester sur la bonne voie.


⏭️ Prochaines étapes et améliorations futures

Une autre étape pourrait consister à étendre cette approche à d'autres parties du pipeline qui nécessitent une gestion dynamique des noms de champs, car qui n'aime pas un peu d'automatisation⚙️ ?


?️ Outils et ressources ?

  1. Documentation Go : pour plonger dans la syntaxe Go et comprendre les concepts de base.
  2. Instill Docs : une mine d'or de ressources bien organisées pour comprendre le pipeline Instill.
  3. Go Testing Framework : le package de tests intégré à Go pour écrire des tests unitaires, garantir que tout fonctionne comme prévu et s'intégrer aux outils CI.
  4. Golangci-lint : un agrégateur Go linters pour identifier les problèmes et garantir la qualité du code pendant le développement et les vérifications CI.

???‍???️ Mon apprentissage

Grâce à la documentation solide d'Instill, aux conseils de ChunHao et au soutien moral d'Anni, ce projet est devenu une fantastique expérience d'apprentissage. Je suis passé de ne rien savoir de Go à l'implémentation d'une fonctionnalité entièrement fonctionnelle prête pour la production (et j'ai le PR fusionné pour le prouver ?).

Preuve :

From Zero to Merge: Building a JSON Renaming Field Component in Go

以上是从零到合并:在 Go 中构建 JSON 重命名字段组件的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板