7 Min. LesezeitEngineering

Auslieferung der Dub.co-Migration: Ordner werden zu Tags abgeflacht

Wie wir One-Click-Dub.co-Importe für Elido entwickelt haben – die sauberste API der fünf, Folder-zu-Tag-Abflachung und warum das Side-Grade für Teams ist, denen EU-Residenz wichtig ist.

Marius Voß
DevRel · edge infra
Pipeline-Diagramm: Dub.co REST-API links, fließend durch den Elido-Import-Worker in die Link-Tabelle, mit einem Seitenpanel, das die numerischen Garantien auflistet (50k Limit, 30 Min. Budget, 100 pro Seite, Ordner werden zu Tags abgeflacht)

Die fünfte und letzte Migrationsquelle in unserem Tier-3-Rollout wurde heute ausgeliefert. Fügen Sie einen Dub.co API-Token ein, filtern Sie optional nach Project-Slug, klicken Sie auf Start. Drei bis fünf Minuten später liegt jeder Link auf Ihrer Elido-Domain, wobei der Slug erhalten bleibt und die Dub-Ordnerstruktur in Elido-Tags abgeflacht wird.

Dieser Beitrag ist der Engineering-Bericht - was für Dub spezifisch ist, warum ihre API die sauberste der fünf von uns unterstützten Anbieter ist und was ein Dub-zu-Elido-Side-Grade motiviert.

Warum diese Migration existiert

Dub.co ist das nächste Open-Source-Äquivalent zu Elido im Funktionsumfang. Starkes Produkt, saubere REST-API, modernes Dashboard. Der Migrationspfad hier ist für Teams gedacht, die sich aus einem von drei Gründen für Elido entscheiden:

  • EU-Residenz. Elidos Data Plane ist in der EU verankert - EU-Region- und US-East-POPs, ein APAC-POP, alle Click-Events landen standardmäßig in unserem Analysespeicher in der EU-Region. Dub Cloud ist in den USA verankert; die GDPR/Schrems-II-Position ist der Kompromiss.
  • Edge-POP-Footprint. Drei regionale POPs mit p95 < 15ms Cache-HIT sind ein anderes Latenzziel als der reine Cloudflare-Workers-Pfad von Dub. Latenzsensitive Workloads (mobile-first, Ad-Attribution) spüren den Unterschied.
  • Analytics-Tiefe. Click-Analytics auf Basis unseres Analysespeichers mit pro-Event-Retention, Conversion-Forwarding zu GA4/Meta CAPI und vollständigem historischen Replay. Dubs Analytics ist sauber, aber PostgreSQL-aggregiert; die Grenze der Tiefe ist eine andere.

Wenn keiner dieser Punkte zutrifft, ist Dub ein gutes Produkt. Die Migration ist für die Teams da, auf die sie zutrifft.

Warum Dubs API die sauberste ist

Wir haben jetzt Worker gegen fünf Vendor-APIs gebaut. Ranking nach Integrationsfreundlichkeit:

  1. Dub.co - Bearer-Token, JSON-RFC-konforme Fehler, ?page= + ?limit=100 Paginierung, jedes Feld dokumentiert mit Beispiel-Payloads.
  2. Short.io - sauber, HasMore-Boolean explizit, aber pro-Domain-Partitionierung benötigt UX-Arbeit.
  3. Bitly - pagination.next URL ist standardkonform; die umgebende API-Referenz ist gründlich.
  4. TinyURL - nur Pro/Bulk, der Rest ist nicht unterstützt; Dokumentation ist spärlich.
  5. Rebrandly - ?last=<id> Cursor ist okay, aber das 25-pro-Seite-Limit lässt alles langsam wirken.

Dubs Vorteil: Ihre Dokumentation enthält curl-Beispiele, ihre Fehlerantworten enthalten sowohl einen Maschinencode als auch eine menschenlesbare Nachricht, und ihre Paginierung ist die langweilige Art, bei der ?page=2&limit=100 genau so funktioniert, wie man es vermuten würde.

Fünf Migrations-Anbieter-APIs nach Integrationsfreundlichkeit bewertet: Dub.co auf Platz 1, dann Short.io, Bitly, TinyURL und Rebrandly am Ende mit 25 pro Seite
const dubPageSize = 100

page := 1
for {
    resp, err := w.fetchPage(ctx, opts.Token, opts.WorkspaceID, page)
    if err != nil { /* mark failed */ return }
    if len(resp) == 0 { break }
    for _, link := range resp { /* import */ }
    if len(resp) < dubPageSize { break }
    page++
}

Dub gibt kein HasMore-Flag zurück; wir leiten es von einer kurzen Seite ab. Dies ist das Standard-REST-Paginierungsmuster und es funktioniert einwandfrei - eine Seite, die kürzer ist als das Limit, bedeutet, dass wir fertig sind.

Ordner werden zu Tags abgeflacht

Dub hat sowohl Ordner als auch Tags als Organisationsprimitive. Elido hat nur Tags. Also flacht die Migration Dub-Ordner in den Tag-Bag ab:

tags := make([]string, 0, len(link.Tags)+2)
for _, t := range link.Tags {
    tags = append(tags, t.Name)
}
if link.Folder != nil && link.Folder.Name != "" {
    // Dub-Ordner können verschachtelt sein; den vollständigen Pfad abflachen.
    for _, segment := range strings.Split(link.Folder.Name, "/") {
        seg := strings.TrimSpace(segment)
        if seg != "" {
            tags = append(tags, seg)
        }
    }
}
tags = append(tags, "imported:dub")
Ein Dub-Link im Ordner campaigns/q3-launch mit den Tags paid und linkedin, der in einen Elido-Tag-Bag aus paid, linkedin, campaigns, q3-launch und imported:dub abgeflacht wird

Ein Dub-Link im Ordner campaigns/q3-launch mit Tags paid und linkedin importiert mit den Tags paid, linkedin, campaigns, q3-launch und imported:dub. Die Filtersemantik in Elido handhabt dieselben Abrufmuster wie Dubs Ordner-UI - tag-equals, tag-contains, multi-tag-AND. Wir erfinden die Ordnerhierarchie nicht serverseitig neu; der Benutzer erhält eine flache Liste von Tags und die Filterprimitive.

Hätten wir Elido Ordner hinzufügen können? Ja. Wir entschieden uns für nur Tags, als Elidos Datenmodell in Phase 1 ausgeliefert wurde; Ordner sind sinnvoll für Desktop-Dateisystem-Mentalmodelle und weniger für Short-Link-Bulk-Operationen. Dub-Benutzer in Elido-Tags zu migrieren, ist die richtige Seite dieses Kompromisses.

Projektfilterung

Dub verwendet "Workspaces" (in ihrer neueren UI) und nannte sie historisch "Projekte". Die API akzeptiert einen workspaceId-Parameter zum Filtern; der Launcher macht ihn als optionales Textfeld zugänglich. Fügen Sie den Workspace-Slug aus Ihrer Dub-URL ein oder lassen Sie ihn leer, um jeden Link zu greifen, den der Token sehen kann.

Dies spiegelt den Rebrandly-Workspace-Filter und das Short.io-Domainfeld wider. Drei unserer fünf Migrationsanbieter haben ein Pro-Account-Partitionierungskonzept; wir stellen es konsistent als optionale Texteingabe dar anstatt als befülltes Dropdown, da der typische Benutzer höchstens zwei Workspaces hat und der API-Listing-Endpunkt Latenz hinzufügt, die den Schliff nicht wert ist.

Was wir nicht migrieren

Dubs Geo-Targeting- und Device-Targeting-Regeln. Sie sind ein mächtiges Dub-Feature, aber die Regelform lässt sich nicht 1:1 auf Elido Smart-Link-Regeln abbilden. Der Slug importiert; bauen Sie die Regeln mit Elidos Ausdruckssyntax neu auf, die permissiver ist, aber eine andere mentale Form hat.

Pro-Click-Historie. Universelles Limit über alle fünf Migrationsquellen hinweg. Dubs Pro-Click-Daten liegen hinter ihrem Analytics-Endpunkt, der an den Plantarif gebunden ist; neue Klicks landen ab dem Cutover in Elido-Analytics.

QR-Styling. Der Standard-Elido-QR wird neu generiert; benutzerdefinierte Designs müssen neu angewendet werden. Das imported:dub-Tag ist der Handle für die Bulk-Neuzuweisung.

Dub-Workspace-ACLs und Rollenkonfiguration. Gewähren Sie den Zugriff in Elido neu mittels SCIM/SSO oder Workspace-Mitgliedseinladungen; das Rollenmodell unterscheidet sich zwischen den beiden Produkten stark genug, dass ein automatisches Mapping als stille Privilegien-Eskalation erscheinen würde.

Die Dub-Import-Pipeline von der REST-API durch den Elido-Worker in die Link-Tabelle, mit einer nebeneinander stehenden Liste was migriert wird und was nicht

Selbstgehostetes Dub

Dub ist Open-Source und selbstgehostete Dub-Instanzen sind üblich. Die Migration verwendet dieselbe REST-API, die das Dub-Cloud-Produkt offenlegt, daher bedeutet das Zeigen auf ein selbstgehostetes Dub, DUB_API_BASE zu überschreiben. Wir haben das in v1 nicht als Self-Serve-Einstellung freigegeben, da der operative Rattenschwanz nicht trivial ist - verschiedene Dub-Versionen legen subtil unterschiedliche Antwortformen offen, und wir wollen keinen Launcher ausliefern, der auf einem Dub v0.7-Deployment stillschweigend 500er-Fehler wirft, wenn v0.9 das getestete Ziel ist.

Für selbstgehostete Dub-Migrationen senden Sie eine E-Mail an [email protected] mit Ihrer Dub-Version, und wir führen eine einmalige Concierge-Migration durch. Sobald wir genug Versionen in freier Wildbahn gesehen haben, wird der Override zu einer Self-Serve-Dashboard-Einstellung.

Token-Behandlung

Dieselbe One-Shot-Semantik wie bei den vier anderen Migrationsanbietern:

bgCtx := context.WithoutCancel(r.Context())
go h.dub.Run(bgCtx, job.ID, imports.DubJobOptions{
    Token:       req.Token,
    WorkspaceID: req.WorkspaceID,
})

source_token_id bleibt NULL. Der Token lebt im api-core-Prozessspeicher für den Worker-Lauf und wird nach Abschluss verworfen. Keine Persistenz - dies ist eine One-Shot-Migration, kein wiederkehrender Vendor-Call.

context.WithoutCancel (Go 1.21+) hält den Worker über den HTTP-Request hinaus am Leben. Dasselbe Muster wie bei jedem anderen Migrationsanbieter in diesem Rollout.

Konfliktlösung und der Worker-Vertrag

Identisch mit jedem anderen Anbieter. Suffix-Walks mylink-2, mylink-3, …, bis zu 50 Kandidaten; Skip lässt den bestehenden Elido-Link in Ruhe; Fail bricht beim ersten Konflikt ab. Worker-Vertrag - MaxLinksPerImport=50_000, ImportRunBudget=30*time.Minute - wird über alle fünf geteilt.

Der Lookup ist ein indizierter Read pro Zeile auf (domain_id, slug). Deterministische Suffix-Walks, freundlichere Fehler als das Fischen nach Uniqueness-Verletzungen in pgx.

Was wir mit Bitly verglichen haben

Sowohl Dub als auch Bitly migrieren mit ungefähr demselben Durchsatz - 100 Links pro Seite, ~5 Inserts/Sek. anhaltend. Eine 5.000-Link-Quelle ist bei beiden Anbietern in 4–7 Minuten fertig. Der benutzer sichtbare Unterschied ist die Post-Import-Erfahrung: Dub-importierte Links kommen mit strukturierten Ordner-als-Tag-Breadcrumbs an; Bitly-importierte Links kommen nur mit dem imported:bitly-Tag und allen frei formatierten Bitly-Tags an.

Wiederaufnehmbarkeit und das Deploy-Problem

Dasselbe Kompromiss wie bei den ersten vier Migrationen. Worker ist in-process; ein Mid-Import-Deploy tötet die Goroutine. Der 5-Minuten-Stuck-Sweep-Cron dreht jede running-Zeile ohne Fortschritt in 30 Minuten auf failed. Das erneute Ausführen ist idempotent unter Suffix- und Skip-Strategien.

Für Accounts über 10.000 Links würde sich die Wiederaufnehmbarkeit lohnen - wir würden den Dub-page-Cursor in import_jobs.source_filter aufzeichnen und ab der letzten abgeschlossenen Seite fortfahren. Alle fünf Migrationsanbieter teilen das gleiche In-Process-Design; wenn wir Wiederaufnehmbarkeit ausliefern, profitieren alle fünf.

Was kommt als nächstes für den Tier-3-Rollout

Tier-3 ist fertig. Fünf Migrationsanbieter, eine geteilte import_jobs-Tabelle, ein geteilter Worker-Vertrag, eine geteilte Dashboard-Polling-UI, fünf SEO-Landings, fünf Engineering-Blogposts.

Was hinter Tier-3 in der Warteschlange steht:

  • Wiederaufnehmbarkeit für Accounts nördlich von 10.000 Links. Vendor-spezifisches Cursor-Checkpointing.
  • CSV-Export-Fallback für Benutzer auf Plänen mit widerrufenen Tokens. Derzeit nur Concierge.
  • Tier-2 service_tokens Fundament - Vendor-Tokens zur wiederkehrenden Nutzung für Mailchimp, Brevo, Klaviyo. Der Migrationspfad validierte das JSONB-source_filter-Muster; Tier-2 benötigt persistente verschlüsselte Tokens, was ein separater Secrets-at-Rest-Arbeitsstrang ist.

Wenn Sie Elido von einem Dub-Workspace aus beobachtet haben, ist die Migrationsgeschichte jetzt dokumentiert. Probieren Sie es aus - Token bis zum letzten importierten Link in unter fünf Minuten bei typischen Accounts.

Verwandtes im Blog

Elido testen

URL einfügen, kurzer Link in Sekunden

Kein Konto nötig. Link bleibt 30 Tage aktiv. Konto erstellen, um ihn dauerhaft zu behalten.

Kostenlos, keine Anmeldung erforderlich · 2 pro Tag

Elido testen

URL-Shortener mit EU-Hosting: eigene Domains, tiefe Analytik und eine offene API. Kostenloser Tarif - keine Kreditkarte nötig.

Tags
dub.co migration
url shortener
go worker
data migration
engineering
tier 3 integrations

Weiterlesen