restserver

package
v0.0.0-...-b8169c9 Latest Latest
Warning

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

Go to latest
Published: May 26, 2022 License: BSD-3-Clause Imports: 10 Imported by: 0

Documentation

Overview

Package restserver implements an http.Handler that executes Redis commands over a REST API. It aims to be compatible with the Upstash Redis REST API [1], and as such implements its custom ACL RESTTOKEN command and returns compatible payloads and status codes. It can be used e.g. as a Web server for testing. See also the cmd/upstash-redis-rest-server command that implements a Web server based on this package.

Usage

Create a Server value by setting its APIToken and GetConnFunc fields, and mount it on an http.Server web server. The *Server type implements http.Handler.

Authorization

Only requests that provide a valid API token are authorized. Valid API tokens are the one specified when creating the Server value (by setting its APIToken field), and any other token generated by executing the ACL RESTTOKEN command with a valid Redis username and password. Using this token results in executing the command(s) as this user, with their access rights and restrictions. See [2] and [3] for more details.

[1]: https://docs.upstash.com/redis/features/restapi
[2]: https://redis.io/docs/manual/security/acl/
[3]: https://docs.upstash.com/redis/features/restapi#rest-token-for-acl-users

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Conn

type Conn interface {
	// Close closes the connection.
	Close() error

	// Do sends a command to the server and returns the received reply.
	Do(commandName string, args ...interface{}) (reply interface{}, err error)
}

Conn defines the methods required for a redis connection. It is a subset of the popular redigo Conn interface.

type Server

type Server struct {
	// APIToken is the admin API token that must be used to authenticate
	// requests, unless ACL RESTTOKEN is used to generate other valid API tokens.
	APIToken string

	// GetConnFunc must be set to a function that returns a Conn value to execute
	// the actual commands against a Redis database. The redigo package is
	// straightforward to use with this function signature.
	GetConnFunc func(context.Context) Conn
	// contains filtered or unexported fields
}

Server implements an http.Handler that serves Redis commands via a REST API compatible with the Upstash Redis REST API.

Example (Dial)
package main

import (
	"context"
	"net/http/httptest"

	"github.com/gomodule/redigo/redis"
	"github.com/mna/upstashdis/restserver"
)

// create a failed connection type for when Dial fails to get a connection.
type failedConn struct {
	err error
}

// implement the restserver.Conn interface, returning the error for each call.
func (f failedConn) Do(_ string, _ ...interface{}) (interface{}, error) {
	return nil, f.err
}

func (f failedConn) Close() error {
	return f.err
}

func main() {
	// configure the REST server to get connections by dialing to a running Redis
	// instance.
	server := &restserver.Server{
		APIToken: "<token>",
		GetConnFunc: func(ctx context.Context) restserver.Conn {
			conn, err := redis.DialContext(ctx, "tcp", "localhost:6379")
			if err != nil {
				return failedConn{err: err}
			}
			return conn
		},
	}

	// create a test web server to serve the REST server.
	httpsrv := httptest.NewServer(server)
	defer httpsrv.Close()

	// the REST server is available at httpsrv.URL
}
Output:

Example (Pool)
package main

import (
	"context"
	"net/http/httptest"

	"github.com/gomodule/redigo/redis"
	"github.com/mna/upstashdis/restserver"
)

func main() {
	// create the redigo pool, connecting to a running Redis instance
	pool := redis.Pool{
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", "localhost:6379")
		},
	}
	defer pool.Close()

	// configure the REST server to get connections from that pool
	server := &restserver.Server{
		APIToken: "<token>",
		GetConnFunc: func(ctx context.Context) restserver.Conn {
			return pool.Get()
		},
	}

	// create a test web server to serve the REST server.
	httpsrv := httptest.NewServer(server)
	defer httpsrv.Close()

	// the REST server is available at httpsrv.URL
}
Output:

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler for the REST API server.

Jump to

Keyboard shortcuts

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