semanticid

package module
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2022 License: MIT Imports: 12 Imported by: 0

README

SemanticID

Build Status codecov GoDoc Go Report Card

SemanticIDs are a special type of ID, providing extra utility especially in the context of microservice infrastructures.

SemanticIDs consist of 3 parts:

<namespace>.<collection>.<id>

By choosing a meaningful namespace and collection, you can glean a lot of information about an ID just by looking at it. The unique ID part uses ULIDs by default, but can easily be changed to using UUIDv4.

You can also optionally add in your own ID provider, which will allow you to customize ID generation as well as validation. This can be done globally or on a case-by-case basis by using the Builder.

Usage

SemanticID uses go modules internally, so it will seamlessly integrate with other projects using modules. This also means that go 1.11+ is required.
To use the library, simply do:

$ go get -u github.com/happenslol/semanticid

Then, import it into your code:

import "github.com/happenslol/semanticid"

Here's a simple example that shows how to create and parse IDs:

semanticid.DefaultNamespace = "myservice"
semanticid.DefaultCollection = "entities"

sid := semanticid.Must(semanticid.NewDefault())

parsed, err := semanticid.FromString(toParse)
if err != nil {
  fmt.Printf("something went wrong while parsing: %v", err)
}

Here are some more examples for common use cases:

// Switch to UUIDv4
semanticid.DefaultIDProvider = semanticid.NewUUIDProvider()

// Use a custom provider just for a single ID
type MyProvider struct {}

func (p *MyProvider) Generate() (string, error) {
  return "1234", nil
}

func (p *MyProvider) Validate(id string) {
  return nil
}

customID, err := semanticid.Builder().
  WithIDProvider(&MyProvider{}).
  WithCollection("custom-id-entity").
  Build()

// Parse a semantic id without ID validation
sid, _ := semanticid.Builder().
  FromString("a.b.c").
  NoValidate().
  Build()

Choosing namespace and collection

While you can generally choose any namespace and collection you want, here are a few guidelines that should make SemanticIDs more useful and consistent throughout your infrastructure:

Choose a namespace that suggests in which part of your infrastructure the ID was created. This could be the name of the microservice, the name of the external service the ID refers to, or your company's or project's name.

Use the plural of the entity name as the collection. This is just a convention, but it generally leads to very readable IDs and connects well with other parts of your applications - in practice, you can probably reuse that database name or URL for a specific entity as the collection name.

Only use lowercase letters and no special characters in the namespace and collection. This reduces visual noise and makes sure your IDs always stay URL safe and unambiguous.

Examples for good SemanticIDs:

accountservice.users.7da57b46-f4f4-4824-a8e8-0c05ff88d9a5
github.repos.87961165-15f0-4fb8-8d8b-d9ce59034565
blog.posts.59731722-54ea-4447-8e99-f4689c0c060a

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrEmpty                 = &SemanticIDError{errEmpty, ""}
	ErrIDProvider            = &SemanticIDError{errIDProviderError, ""}
	ErrInvalid               = &SemanticIDError{errInvalidSID, ""}
	ErrInvalidIDPart         = &SemanticIDError{errInvalidID, ""}
	ErrPartContainsSeparator = &SemanticIDError{errPartContainsSeparator, ""}
)
View Source
var DefaultCollection = "collection"

DefaultCollection is the collection that will be used if no collection is specified when creating a SemanticID.

View Source
var DefaultNamespace = "namespace"

DefaultNamespace is the namespace that will be used if no namespace is specified when creating a SemanticID.

View Source
var Separator = "."

Separator that will be used for all SemanticIDs. You should set this once and never change it for your application - Once you change it, SemanticIDs created before that point can't be parsed anymore. By default, this is set to `.` since this makes SemanticIDs entirely URL-safe.

Functions

func CollectionForModel added in v1.0.0

func CollectionForModel(model interface{}) (string, error)

CollectionForModel returns the collection defined in the `sid` tag on the `ID` field of the passed struct.

func CollectionForModelField added in v1.0.0

func CollectionForModelField(model interface{}, field string) (string, error)

CollectionForModelField returns the collection defined in the `sid` tag on the given field.

func RegisterValidation added in v1.1.0

func RegisterValidation(v *validator.Validate) error

func SemanticIDTypeFunc added in v1.1.0

func SemanticIDTypeFunc(field reflect.Value) interface{}

func SemanticIDValidation added in v1.1.0

func SemanticIDValidation(fl validator.FieldLevel) bool

func ToStrings added in v1.3.0

func ToStrings(s []SemanticID) []string

ToStrings converts a list of semanticids to their string representation.

Types

type BSONSemanticIDCodec

type BSONSemanticIDCodec struct{}

BSONSemanticIDCodec is a mongodb ValueCodec for encoding and decoding SemanticIDs to and from BSON.

func (*BSONSemanticIDCodec) DecodeValue

DecodeValue implements the ValueDecoder interface.

func (*BSONSemanticIDCodec) EncodeValue

EncodeValue implements the ValueEncoder interface.

type BSONSemanticIDPointerCodec

type BSONSemanticIDPointerCodec struct{}

BSONSemanticIDCodec is a mongodb ValueCodec for encoding and decoding SemanticIDs to and from BSON.

func (*BSONSemanticIDPointerCodec) DecodeValue

DecodeValue implements the ValueDecoder interface.

func (*BSONSemanticIDPointerCodec) EncodeValue

EncodeValue implements the ValueEncoder interface.

type IDProvider added in v1.0.0

type IDProvider interface {
	// Generate generates a random ID
	Generate() (string, error)
	// Validate validates an existing ID
	Validate(id string) error
}

IDProvider represents a type that can generate and validate the ID part of semanticids. By default, ULIDs will be used for this, since they offer lots of benefits over UUIDs, but a UUID provider is provided and custom providers can easily be used by either setting the default ID Provider or using the builder.

var DefaultIDProvider IDProvider = NewULIDProvider()

DefaultIDProvider determines the provider that will be used to generate and validate IDs. You can either set this or use the builder to select the provider on an individual basis.

type SemanticID

type SemanticID struct {
	Namespace  string
	Collection string
	ID         string
}

A SemanticID is a unique identifier for an entity that consists of a namespace, a collection and an ID.

func FromString

func FromString(s string) (SemanticID, error)

FromString attempts to parse a given string into a SemanticID.

func FromStrings added in v1.2.0

func FromStrings(s []string) ([]SemanticID, error)

FromStrings attempts to parse a given list of strings into a list of SemanticIDs. An error will be returned for the first conversion that errors, which means that a list that returns an error is not guaranteed to only contain that one error.

func Must

func Must(sID SemanticID, err error) SemanticID

Must is a convenience function that converts errors into panics on functions that create or parse a SemanticID.

func New

func New(namespace, collection string) (SemanticID, error)

New creates a unique SemanticID with the given namespace, collection and the global separator (`.` by default).

func NewDefault

func NewDefault() (SemanticID, error)

NewDefault creates a unique SemanticID with the default namespace and collection.

func NewForModel added in v1.0.0

func NewForModel(model interface{}) (SemanticID, error)

NewForModel creates a unique SemanticID using the collection defined in the `sid` tag in the given model.

func NewWithCollection

func NewWithCollection(collection string) (SemanticID, error)

NewWithCollection creates a unique SemanticID with the given collection and the default namespace.

func NewWithNamespace

func NewWithNamespace(namespace string) (SemanticID, error)

NewWithNamespace creates a unique SemanticID with the given namespace and the default collection.

func (SemanticID) Is added in v1.2.0

func (sID SemanticID) Is(identity string) bool

Is checks the identity of a SemanticID, given by its Namespace and Collection. It expects a dot-separated Namespace and Collection combination, such that `semanticid.New("auth", "users").Is("auth.users") == true`.

func (SemanticID) IsNil

func (sID SemanticID) IsNil() bool

IsNil checks whether or not the SemanticID has any of its part set to a non-null string.

func (SemanticID) MarshalJSON

func (sid SemanticID) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for SemanticID

func (SemanticID) String

func (sID SemanticID) String() string

String outputs a string representation of the SemanticID

func (*SemanticID) UnmarshalJSON

func (sid *SemanticID) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for SemanticID

type SemanticIDBuilder added in v1.0.0

type SemanticIDBuilder struct {
	// contains filtered or unexported fields
}

func Builder added in v1.0.0

func Builder() *SemanticIDBuilder

func (*SemanticIDBuilder) Build added in v1.0.0

func (b *SemanticIDBuilder) Build() (SemanticID, error)

func (*SemanticIDBuilder) FromString added in v1.0.0

func (b *SemanticIDBuilder) FromString(s string) *SemanticIDBuilder

func (*SemanticIDBuilder) NoValidate added in v1.0.0

func (b *SemanticIDBuilder) NoValidate() *SemanticIDBuilder

func (*SemanticIDBuilder) WithCollection added in v1.0.0

func (b *SemanticIDBuilder) WithCollection(collection string) *SemanticIDBuilder

func (*SemanticIDBuilder) WithIDProvider added in v1.0.0

func (b *SemanticIDBuilder) WithIDProvider(idp IDProvider) *SemanticIDBuilder

func (*SemanticIDBuilder) WithNamespace added in v1.0.0

func (b *SemanticIDBuilder) WithNamespace(namespace string) *SemanticIDBuilder

type SemanticIDError added in v1.1.1

type SemanticIDError struct {
	// contains filtered or unexported fields
}

func (*SemanticIDError) Error added in v1.1.1

func (err *SemanticIDError) Error() string

func (*SemanticIDError) Is added in v1.1.1

func (err *SemanticIDError) Is(target error) bool

type ULIDProvider added in v1.0.0

type ULIDProvider struct{}

func NewULIDProvider added in v1.0.0

func NewULIDProvider() *ULIDProvider

func (*ULIDProvider) Generate added in v1.0.0

func (up *ULIDProvider) Generate() (string, error)

func (*ULIDProvider) Validate added in v1.0.0

func (up *ULIDProvider) Validate(id string) error

type UUIDProvider added in v1.0.0

type UUIDProvider struct{}

func NewUUIDProvider added in v1.0.0

func NewUUIDProvider() *UUIDProvider

func (*UUIDProvider) Generate added in v1.0.0

func (up *UUIDProvider) Generate() (string, error)

func (*UUIDProvider) Validate added in v1.0.0

func (up *UUIDProvider) Validate(id string) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL