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",
|
"info": "redirects to given tiny url",
|
||||||
"scope": [[]],
|
"scope": [[]],
|
||||||
"in": {
|
"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": {}
|
"out": {}
|
||||||
},
|
},
|
||||||
|
@ -13,10 +13,29 @@
|
||||||
"info": "creates a new tiny url",
|
"info": "creates a new tiny url",
|
||||||
"scope": [[]],
|
"scope": [[]],
|
||||||
"in": {
|
"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)" }
|
"target": { "info": "url to shorten", "type": "varchar(5,300)" }
|
||||||
},
|
},
|
||||||
"out": {}
|
"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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
e "git.xdrm.io/go/xb-api/err"
|
e "git.xdrm.io/go/xb-api/err"
|
||||||
i "git.xdrm.io/go/xb-api/implement"
|
i "git.xdrm.io/go/xb-api/implement"
|
||||||
r "github.com/go-redis/redis"
|
"github.com/go-redis/redis"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Initiates connection to redis dataset
|
const NONCE = "go-tiny-url"
|
||||||
func redisConnect() (*r.Client, error) {
|
|
||||||
cli := r.NewClient(&r.Options{
|
type db redis.Client
|
||||||
|
|
||||||
|
// Returns a connected client to dataset
|
||||||
|
func connect() *db {
|
||||||
|
cli := redis.NewClient(&redis.Options{
|
||||||
Addr: "127.0.0.1:6379",
|
Addr: "127.0.0.1:6379",
|
||||||
Password: "",
|
Password: "",
|
||||||
DB: 0,
|
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
|
// Redirects to an url from a key
|
||||||
func Get(d i.Arguments, r *i.Response) i.Response {
|
func Get(d i.Arguments, r *i.Response) i.Response {
|
||||||
|
|
||||||
/* (1) Init redis connection */
|
/* (1) Init redis connection */
|
||||||
cli, err := redisConnect()
|
cli := connect()
|
||||||
if err != nil {
|
if cli == nil {
|
||||||
r.Err = e.Failure
|
r.Err = e.Failure
|
||||||
return *r
|
return *r
|
||||||
}
|
}
|
||||||
|
@ -39,14 +88,14 @@ func Get(d i.Arguments, r *i.Response) i.Response {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (3) Check if match for this key */
|
/* (3) Check if match for this key */
|
||||||
val, err := cli.Get(key).Result()
|
val := cli.get(key)
|
||||||
if err != nil {
|
if val == nil {
|
||||||
r.Err = e.NoMatchFound
|
r.Err = e.NoMatchFound
|
||||||
return *r
|
return *r
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (4) Redirect to value */
|
/* (4) Redirect to value */
|
||||||
r.Set("_REDIRECT_", val)
|
r.Set("_REDIRECT_", string(val))
|
||||||
r.Err = e.Success
|
r.Err = e.Success
|
||||||
return *r
|
return *r
|
||||||
}
|
}
|
||||||
|
@ -54,8 +103,8 @@ func Get(d i.Arguments, r *i.Response) i.Response {
|
||||||
// Stores a new tinyurl/fullurl combination
|
// Stores a new tinyurl/fullurl combination
|
||||||
func Post(d i.Arguments, r *i.Response) i.Response {
|
func Post(d i.Arguments, r *i.Response) i.Response {
|
||||||
/* (1) Init redis connection */
|
/* (1) Init redis connection */
|
||||||
cli, err := redisConnect()
|
cli := connect()
|
||||||
if err != nil {
|
if cli == nil {
|
||||||
r.Err = e.Failure
|
r.Err = e.Failure
|
||||||
return *r
|
return *r
|
||||||
}
|
}
|
||||||
|
@ -70,15 +119,82 @@ func Post(d i.Arguments, r *i.Response) i.Response {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (3) Check if key already used */
|
/* (3) Check if key already used */
|
||||||
_, err = cli.Get(url).Result()
|
if cli.get(url) != nil {
|
||||||
if err == nil {
|
|
||||||
r.Err = e.AlreadyExists
|
r.Err = e.AlreadyExists
|
||||||
return *r
|
return *r
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (4) Store */
|
/* (4) Store */
|
||||||
err = cli.Set(url, target, 0).Err()
|
if !cli.set(url, target) {
|
||||||
if err != nil {
|
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
|
r.Err = e.Failure
|
||||||
return *r
|
return *r
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue