<commit_before>// Copyright (c) 2014, <NAME>

// rst relies on esc (https://github.com/mjibson/esc) to embed static resources
// with go generate (requires go 1.4 or more recent).
//go:generate esc -pkg=rst -o=assets.go ./assets

/*
Package rst implements tools and methods to expose resources in a RESTFul
web service.

The idea behind rst is to have endpoints and resources implement interfaces to
add features.

Endpoints can implement Getter, Poster, Patcher, Putter or Deleter to
respectively allow the HEAD/GET, POST, PATCH, PUT, and DELETE HTTP methods.

Resources can implement Ranger to support partial GET requests, Marshaler to
customize the process with which they are encoded, or http.Handler to have a
complete control over the ResponseWriter.

With these interfaces, the complexity behind dealing with all the headers and
status codes of the HTTP protocol is abstracted to let you focus on returning a
resource or an error.

Resources

A resource must implement the Resource interface. Here's a basic example:

	type Person struct {
		ID string
		Name string
		ModifiedDate time.Time `json:"-" xml:"-"`
	}

	// This will be helpful for conditional GETs
	// and to detect conflicts before PATCHs for example.
	func (p *Person) LastModified() time.Time {
		return p.ModifiedDate
	}

	// An ETag inspired by Facebook.
	func (p *Person) ETag() string {
		return fmt.Sprintf("%d-%s", p.LastModified().Unix(), p.ID)
	}

	// This value will help set the Expires header and
	// improve the cacheability of this resource.
	func (p *Person) TTL() time.Duration {
		return 10 * time.Second
	}

Endpoints

An endpoint is an access point to a resource in your service.

In the following example, PersonEP implements Getter and is therefore able to
handle GET requests.

	type PersonEP struct {}

	func (ep *PersonEP) Get(vars rst.RouteVars, r *http.Request) (rst.Resource, error) {
		resource := database.Find(vars.Get("id"))
		if resource == nil {
			return nil, rst.NotFound()
		}
		return resource, nil
	}

Get uses the id variable extracted from the URL to load a resource from the
database, or return a 404 Not Found error.

Routing

Routing of requests in rst is powered by Gorilla mux
(https://github.com/gorilla/mux). Only URL patterns are available for now.
Optional regular expressions are supported.

	mux := rst.NewMux()
	mux.Debug = true // make sure this is switched back to false before production

	// Headers set in mux are added to all responses
	mux.Header().Set("Server", "Awesome Service Software 1.0")
	mux.Header().Set("X-Powered-By", "rst")

	mux.Handle("/people/{id:\\d+}", rst.EndpointHandler(&PersonEP{}))

	http.ListenAndServe(":8080", mux)

Encoding

rst supports JSON, XML and text encoding of resources using the encoders in Go's
standard library.

It negotiates the right encoding format based on the content of the Accept
header in the request, calls the appropriate marshaler, and inserts the result
in a response with the right status code and headers.

You can implement the Marshaler interface if you want to add support for another
format, or for more control over the encoding process of a specific resource.

Compression

rst compresses the payload of responses using the supported algorithm detecte
in the request's Accept-Encoding header.

Payloads under CompressionThreshold bytes are not compressed.

Both Gzip and Flate are supported.

Options

OPTIONS requests are implicitly supported by all endpoints.

Cache

The ETag, Last-Modified and Vary headers are automatically set.

rst responds with 304 NOT MODIFIED when an appropriate If-Modified-Since or
If-None-Match header is found in the request.

The Expires header is also automatically inserted with the duration returned by
Resource.TTL().

Partial Gets

A resource can implement the Ranger interface to gain the ability to return
partial responses with status code 206 PARTIAL CONTENT and Content-Range
header automatically inserted.

Ranger.Range method will be called when a valid Range header is found in an
incoming GET request.

The Accept-Range header will be inserted automatically.<commit_msg>Cosmetic improvements to the doc.<commit_after>// Copyright (c) 2014, <NAME>

// rst relies on esc (https://github.com/mjibson/esc) to embed static resources
// with go generate (requires go 1.4 or more recent).
//go:generate esc -pkg=rst -o=assets.go ./assets

/*
Package rst implements tools and methods to expose resources in a RESTFul
web service.

The idea behind rst is to have endpoints and resources implement interfaces to
add features.

Endpoints can implement Getter, Poster, Patcher, Putter or Deleter to
respectively allow the HEAD/GET, POST, PATCH, PUT, and DELETE HTTP methods.

Resources can implement Ranger to support partial GET requests, Marshaler to
customize the process with which they are encoded, or http.Handler to have a
complete control over the ResponseWriter.

With these interfaces, the complexity behind dealing with all the headers and
status codes of the HTTP protocol is abstracted to let you focus on returning a
resource or an error.

Resources

A resource must implement the Resource interface. Here's a basic example:

	type Person struct {
		ID string
		Name string
		ModifiedDate time.Time `json:"-" xml:"-"`
	}

	// This will be helpful for conditional GETs
	// and to detect conflicts before PATCHs for example.
	func (p *Person) LastModified() time.Time {
		return p.ModifiedDate
	}

	// An ETag inspired by Facebook.
	func (p *Person) ETag() string {
		return fmt.Sprintf("%d-%s", p.LastModified().Unix(), p.ID)
	}

	// This value will help set the Expires header and
	// improve the cacheability of this resource.
	func (p *Person) TTL() time.Duration {
		return 10 * time.Second
	}

Endpoints

An endpoint is an access point to a resource in your service.

In the following example, PersonEP implements Getter and is therefore able to
handle GET requests.

	type PersonEP struct {}

	func (ep *PersonEP) Get(vars rst.RouteVars, r *http.Request) (rst.Resource, error) {
		resource := database.Find(vars.Get("id"))
		if resource == nil {
			return nil, rst.NotFound()
		}
		return resource, nil
	}

Get uses the id variable extracted from the URL to load a resource from the
database, or return a 404 Not Found error.

Routing

Routing of requests in rst is powered by Gorilla mux
(https://github.com/gorilla/mux). Only URL patterns are available for now.
Optional regular expressions are supported.

	mux := rst.NewMux()
	mux.Debug = true // make sure this is switched back to false before production

	// Headers set in mux are added to all responses
	mux.Header().Set("Server", "Awesome Service Software 1.0")
	mux.Header().Set("X-Powered-By", "rst")

	mux.Handle("/people/{id:\\d+}", rst.EndpointHandler(&PersonEP{}))

	http.ListenAndServe(":8080", mux)

Encoding

rst supports JSON, XML and text encoding of resources using the encoders in Go's
standard library.

It negotiates the right encoding format based on the content of the Accept
header in the request, calls the appropriate marshaler, and inserts the result
in a response with the right status code and headers.

You can implement the Marshaler interface if you want to add support for another
format, or for more control over the encoding process of a specific resource.

Compression

rst compresses the payload of responses using the supported algorithm detected
in the request's Accept-Encoding header.

Payloads under the size defined in the CompressionThreshold const are not compressed.

Both Gzip and Flate are supported.

Options

OPTIONS requests are implicitly supported by all endpoints.

Cache

The ETag, Last-Modified and Vary headers are automatically set.

rst responds with 304 NOT MODIFIED when an appropriate If-Modified-Since or
If-None-Match header is found in the request.

The Expires header is also automatically inserted with the duration returned by
Resource.TTL().

Partial Gets

A resource can implement the Ranger interface to gain the ability to return
partial responses with status code 206 PARTIAL CONTENT and Content-Range
header automatically inserted.

Ranger.Range method will be called when a valid Range header is found in an
incoming GET request.

The Accept-Range header will be inserted automatically.
{'fraction_non_alphanumeric': 0.0664890396027613, 'fraction_numerical': 0.005571030640668524, 'mean_word_length': 4.1774294670846395, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7066260', 'n_tokens_mistral': 2320, 'n_tokens_neox': 2175, 'n_words': 1134}