code: func (c *Connector) Read(ctx context.Context, ei *dosa.EntityInfo, keys map[string]dosa.FieldValue, fieldsToRead []string) (map[string]dosa.FieldValue, error) {
  	err := validateSchema(ei)
  	if err != nil {
  		return nil, err
  	}
  
  	keyName, valueName := nameOfKeyValue(ei)
  
  	cacheKey, err := buildKey(c.keyPrefix, ei.Ref.Scope, ei.Ref.NamePrefix, ei.Def.Name, keys[keyName])
  	if err != nil {
  		return nil, err
  	}
  
  	cacheValue, err := c.client.Get(cacheKey)
  	c.logHitRate("Read", err)
  	if err != nil {
  		return nil, err
  	}
  
  	result := make(map[string]dosa.FieldValue)
  	// Copy original keys into response
  	for k, v := range keys {
  		result[k] = v
  	}
  	result[valueName] = cacheValue
  	return result, nil
  }
docs: // Read reads an object based on primary key