Il DOI (Digital Object Identifier) è uno standard utilizzato per identificare in modo univoco contenuti digitali, come articoli scientifici, dataset, e pubblicazioni. In questo articolo vedremo come generare e gestire un DOI in Go, simulando l'interazione con le API di registrazione (come quelle di Crossref o DataCite).
1. Cos'è un DOI
Un DOI è una stringa alfanumerica, solitamente composta da un prefisso e un suffisso separati da uno slash. Ad esempio: 10.1234/abcde.2025.001
. I DOI sono generalmente registrati tramite enti certificati che offrono API per la creazione, aggiornamento e risoluzione.
2. Generazione di un DOI
La generazione può essere fatta localmente creando una stringa che segua la sintassi corretta. Ecco un semplice esempio in Go:
package main
import (
"crypto/rand"
"fmt"
)
func generateDOI(prefix string) string {
suffix := make([]byte, 6)
rand.Read(suffix)
for i := range suffix {
suffix[i] = "abcdefghijklmnopqrstuvwxyz0123456789"[suffix[i]%36]
}
return fmt.Sprintf("%s/%s", prefix, string(suffix))
}
func main() {
doi := generateDOI("10.1234")
fmt.Println("DOI generato:", doi)
}
3. Registrazione tramite API
Dopo aver generato un DOI, bisogna registrarlo presso un ente come DataCite. Ecco un esempio di chiamata HTTP POST per registrare un DOI:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type Metadata struct {
Data struct {
Type string `json:"type"`
Attributes struct {
DOI string `json:"doi"`
Title string `json:"titles"`
// Altri metadati
} `json:"attributes"`
} `json:"data"`
}
func registerDOI(doi, title string) error {
metadata := Metadata{}
metadata.Data.Type = "dois"
metadata.Data.Attributes.DOI = doi
metadata.Data.Attributes.Title = title
payload, _ := json.Marshal(metadata)
req, _ := http.NewRequest("POST", "https://api.test.datacite.org/dois", bytes.NewBuffer(payload))
req.Header.Set("Content-Type", "application/vnd.api+json")
req.SetBasicAuth("USERNAME", "PASSWORD")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
return fmt.Errorf("Errore nella registrazione: %s", resp.Status)
}
return nil
}
4. Aggiornamento e gestione
Per aggiornare un DOI registrato, si può effettuare una richiesta HTTP PUT verso lo stesso endpoint:
// Simile alla funzione precedente ma con metodo PUT
req, _ := http.NewRequest("PUT", "https://api.test.datacite.org/dois/10.1234/xyz123", bytes.NewBuffer(payload))
5. Risoluzione di un DOI
I DOI possono essere risolti tramite un semplice redirect usando il sito https://doi.org/
. Ad esempio:
package main
import (
"fmt"
"net/http"
)
func resolveDOI(doi string) error {
url := fmt.Sprintf("https://doi.org/%s", doi)
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Println("Redirect a:", resp.Request.URL)
return nil
}
Conclusione
Generare e gestire un DOI in Go è un processo relativamente semplice, ma che richiede attenzione nella costruzione dei metadati e nell'interazione con le API ufficiali. Per l'uso in produzione è essenziale gestire l'autenticazione in modo sicuro e rispettare le specifiche dell’ente registratore.