full CRUD resource (put for overriding, delete for ...)
This commit is contained in:
parent
15eb1d5e81
commit
3dfdece7e5
|
@ -4,7 +4,7 @@
|
|||
"info": "redirects to given tiny url",
|
||||
"scope": [[]],
|
||||
"in": {
|
||||
"URL#0": { "info": "tiny url to redirect to", "name": "url", "type": "varchar(3,30)" }
|
||||
"URL#0": { "info": "tiny url to redirect to", "name": "url", "type": "varchar(1,30)" }
|
||||
},
|
||||
"out": {}
|
||||
},
|
||||
|
@ -13,10 +13,29 @@
|
|||
"info": "creates a new tiny url",
|
||||
"scope": [[]],
|
||||
"in": {
|
||||
"url": { "info": "preferred tiny url", "type": "varchar(3,30)" },
|
||||
"URL#0": { "info": "preferred tiny url", "type": "varchar(1,30)", "name": "url" },
|
||||
"target": { "info": "url to shorten", "type": "varchar(5,300)" }
|
||||
},
|
||||
"out": {}
|
||||
},
|
||||
|
||||
"PUT": {
|
||||
"info": "overrides an existing tiny url",
|
||||
"scope": [[]],
|
||||
"in": {
|
||||
"URL#0": { "info": "preferred tiny url", "type": "varchar(1,30)", "name": "url" },
|
||||
"target": { "info": "url to shorten", "type": "varchar(5,300)" }
|
||||
},
|
||||
"out": {}
|
||||
},
|
||||
|
||||
"DELETE": {
|
||||
"info": "removes an existing tiny url",
|
||||
"scope": [[]],
|
||||
"in": {
|
||||
"URL#0": { "info": "preferred tiny url", "type": "varchar(1,30)", "name": "url" }
|
||||
},
|
||||
"out": {}
|
||||
}
|
||||
|
||||
}
|
150
root/i.go
150
root/i.go
|
@ -1,30 +1,79 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
e "git.xdrm.io/go/xb-api/err"
|
||||
i "git.xdrm.io/go/xb-api/implement"
|
||||
r "github.com/go-redis/redis"
|
||||
"github.com/go-redis/redis"
|
||||
)
|
||||
|
||||
// Initiates connection to redis dataset
|
||||
func redisConnect() (*r.Client, error) {
|
||||
cli := r.NewClient(&r.Options{
|
||||
const NONCE = "go-tiny-url"
|
||||
|
||||
type db redis.Client
|
||||
|
||||
// Returns a connected client to dataset
|
||||
func connect() *db {
|
||||
cli := redis.NewClient(&redis.Options{
|
||||
Addr: "127.0.0.1:6379",
|
||||
Password: "",
|
||||
DB: 0,
|
||||
})
|
||||
|
||||
_, err := cli.Ping().Result()
|
||||
if _, err := cli.Ping().Result(); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return (*db)(cli)
|
||||
}
|
||||
|
||||
// returns value from key (nil if nothing)
|
||||
func (c *db) get(key string) []byte {
|
||||
|
||||
// 1. Try to get
|
||||
if val, err := c.Get(fmt.Sprintf("%s:%s", NONCE, key)).Result(); err != nil {
|
||||
// 2. nil if nothing found
|
||||
return nil
|
||||
} else {
|
||||
// 3. return if found
|
||||
return []byte(val)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// stores a value for a key (success state in return)
|
||||
func (c *db) set(key string, value string) bool {
|
||||
|
||||
// 1. Try to set
|
||||
if c.Set(fmt.Sprintf("%s:%s", NONCE, key), value, 0).Err() != nil {
|
||||
// 2. failure
|
||||
return false
|
||||
}
|
||||
|
||||
// 3. success
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// deletes the value for a key (success state in return)
|
||||
func (c *db) del(key string) bool {
|
||||
|
||||
// 1. Try to set
|
||||
if c.Del(fmt.Sprintf("%s:%s", NONCE, key)).Err() != nil {
|
||||
// 2. failure
|
||||
return false
|
||||
}
|
||||
|
||||
// 3. success
|
||||
return true
|
||||
|
||||
return cli, err
|
||||
}
|
||||
|
||||
// Redirects to an url from a key
|
||||
func Get(d i.Arguments, r *i.Response) i.Response {
|
||||
|
||||
/* (1) Init redis connection */
|
||||
cli, err := redisConnect()
|
||||
if err != nil {
|
||||
cli := connect()
|
||||
if cli == nil {
|
||||
r.Err = e.Failure
|
||||
return *r
|
||||
}
|
||||
|
@ -39,14 +88,14 @@ func Get(d i.Arguments, r *i.Response) i.Response {
|
|||
}
|
||||
|
||||
/* (3) Check if match for this key */
|
||||
val, err := cli.Get(key).Result()
|
||||
if err != nil {
|
||||
val := cli.get(key)
|
||||
if val == nil {
|
||||
r.Err = e.NoMatchFound
|
||||
return *r
|
||||
}
|
||||
|
||||
/* (4) Redirect to value */
|
||||
r.Set("_REDIRECT_", val)
|
||||
r.Set("_REDIRECT_", string(val))
|
||||
r.Err = e.Success
|
||||
return *r
|
||||
}
|
||||
|
@ -54,8 +103,8 @@ func Get(d i.Arguments, r *i.Response) i.Response {
|
|||
// Stores a new tinyurl/fullurl combination
|
||||
func Post(d i.Arguments, r *i.Response) i.Response {
|
||||
/* (1) Init redis connection */
|
||||
cli, err := redisConnect()
|
||||
if err != nil {
|
||||
cli := connect()
|
||||
if cli == nil {
|
||||
r.Err = e.Failure
|
||||
return *r
|
||||
}
|
||||
|
@ -70,15 +119,82 @@ func Post(d i.Arguments, r *i.Response) i.Response {
|
|||
}
|
||||
|
||||
/* (3) Check if key already used */
|
||||
_, err = cli.Get(url).Result()
|
||||
if err == nil {
|
||||
if cli.get(url) != nil {
|
||||
r.Err = e.AlreadyExists
|
||||
return *r
|
||||
}
|
||||
|
||||
/* (4) Store */
|
||||
err = cli.Set(url, target, 0).Err()
|
||||
if err != nil {
|
||||
if !cli.set(url, target) {
|
||||
r.Err = e.Failure
|
||||
return *r
|
||||
}
|
||||
|
||||
r.Err = e.Success
|
||||
return *r
|
||||
}
|
||||
|
||||
// Overrides a existing tinyurl with new target
|
||||
func Put(d i.Arguments, r *i.Response) i.Response {
|
||||
|
||||
/* (1) Init redis connection */
|
||||
cli := connect()
|
||||
if cli == nil {
|
||||
r.Err = e.Failure
|
||||
return *r
|
||||
}
|
||||
|
||||
/* (2) Extract api input */
|
||||
target, ok1 := d["target"].(string)
|
||||
url, ok2 := d["url"].(string)
|
||||
|
||||
if !ok1 || !ok2 {
|
||||
r.Err = e.InvalidParam
|
||||
return *r
|
||||
}
|
||||
|
||||
/* (3) Check if key already used */
|
||||
if cli.get(url) == nil {
|
||||
r.Err = e.NoMatchFound
|
||||
return *r
|
||||
}
|
||||
|
||||
/* (4) Update */
|
||||
if !cli.set(url, target) {
|
||||
r.Err = e.Failure
|
||||
return *r
|
||||
}
|
||||
|
||||
r.Err = e.Success
|
||||
return *r
|
||||
}
|
||||
|
||||
// Deletes an existing tinyurl
|
||||
func Delete(d i.Arguments, r *i.Response) i.Response {
|
||||
|
||||
/* (1) Init redis connection */
|
||||
cli := connect()
|
||||
if cli == nil {
|
||||
r.Err = e.Failure
|
||||
return *r
|
||||
}
|
||||
|
||||
/* (2) Extract api input */
|
||||
url, ok := d["url"].(string)
|
||||
|
||||
if !ok {
|
||||
r.Err = e.InvalidParam
|
||||
return *r
|
||||
}
|
||||
|
||||
/* (3) Check if key already used */
|
||||
if cli.get(url) == nil {
|
||||
r.Err = e.NoMatchFound
|
||||
return *r
|
||||
}
|
||||
|
||||
/* (4) Delete */
|
||||
if !cli.del(url) {
|
||||
r.Err = e.Failure
|
||||
return *r
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue