Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Functionality to Generate Typesense Schema from Go Structs #152

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

doganarif
Copy link

Change Summary

Based on the changes you've described for adding a new method CreateSchemaFromGoStruct to the go-typesense package, here's an example of how you could frame the context for your pull request:
Change Summary

I've introduced a new feature in the go-typesense package that allows users to automatically generate a Typesense collection schema from a Go struct. This enhancement simplifies the process of schema creation, making it more intuitive and less error-prone, especially for users who manage data structures in Go and want to seamlessly integrate them with Typesense.

The key changes include:

A new method CreateSchemaFromGoStruct that takes a Go struct as input and generates a corresponding Typesense collection schema. This method uses reflection to parse struct fields and tags to build the schema.
Integration of CreateSchemaFromGoStruct with the existing collection creation process, allowing users to create a Typesense collection directly from a Go struct.
Support for the CollectionNamer interface, enabling custom collection naming strategies based on the struct implementation.

PR Context

This enhancement addresses the need for a more streamlined way of creating Typesense schemas directly from Go application data structures. By leveraging Go's reflection capabilities and struct tagging conventions, the CreateSchemaFromGoStruct method automates the conversion of Go structs into Typesense collection schemas.

Key benefits include:

  • Reduced boilerplate code and potential for human error in schema creation.
  • Enhanced flexibility and convenience for developers working with Go and Typesense.
  • The ability to define collection names dynamically via the CollectionNamer interface.

Usage Example

type Product struct {
    ID    string `typesense:"string"`
    Name  string `typesense:"string"`
    Price float64 `typesense:"float"`
}

func main() {
    product := Product{ID: "123", Name: "Gadget", Price: 29.99}
    schema, err := typesense.Collections().CreateSchemaFromGoStruct(product)
    if err != nil {
        log.Fatal(err)
    }
    // Use schema to create a collection in Typesense
}

Tests

Comprehensive tests have been added to ensure the reliability of the new feature, including:

  • Unit tests for schema generation from various struct
  • Integration tests for collection creation using generated schemas.
  • Error handling tests, especially for edge cases and struct tag parsing.

PR Checklist

@DawnKosmos
Copy link

DawnKosmos commented Mar 12, 2024

I really like the Idea of defining the collection schema from a Go struct. At our company we often went out of sync regarding collections definitions and Go structs, also often had unnecessary errors.
I implemented this behaviour with adding additional tags after the json tags.
If interested I can share my code

type Patient struct {
	ID             string   `json:"id,omitempty,index"`
	PatientNumber  string   `json:"patient_number,omitempty,index"`
	Name           string   `json:"name,omitempty,index"`
	Birthdate      int64    `json:"birthdate,omitempty"`
	LastTreatment  int64    `json:"last_treatment,omitempty,index,optional"`
	OrganizationId string   `json:"organization_id,omitempty,facet"`
	LocationId     string   `json:"location_id,omitempty,facet"`
	Roles          []string `json:"roles,omitempty,index"`
}

I also created a tool to generate Typescript interface from a Golang struct.

export interface TypesensePatient {
	id : string; 	// Index
	patient_number : string; 	// Index
	name : string; 	// Index
	birthdate : number; 
	last_treatment ?: number; 	// Index
	organization_id : string; 	// Facet
	location_id : string; 	// Facet
	roles : string[]; 	// Index
}```

@elee1766
Copy link
Contributor

elee1766 commented Apr 8, 2024

i started on this, but realized it was a non trivial task to get the full functionality i wanted, as you would need to figure out the diffs between your structs output and the existing collection to run the migration if the structs ever changed.

instead had to make a small tool with its own state that remembers which migrations have already been run, and just typing out new migrations as json.

@DawnKosmos does your code deal with schema changes? if it does, i am curious if there was an elegant solution, as i did not look too much further into it.

@DawnKosmos
Copy link

Do you mean syncing the Go struct with the Typesense Schema?
I have not implemented it, but I see no problem in doing so.

  1. Download []api.Field From Typesense
  2. Generate []api.Field from Struct
  3. Compare them
  4. Update Schema changes

@doganarif
Copy link
Author

@elee1766, I'm still encountering issues with updating schemas using this code (which I'm using in my projects). @DawnKosmos's approach is okay, but perhaps we should consider enhancing it with migrations like Goose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants