<commit_before># Finch.io Documentation

* [User Guide](docs.md#user-guide)
* [Endpoints](docs.md#endpoints)
* [Requests](docs.md#requests)
  * [Request Reader](docs.md#request-reader-monad)
  * [Multiple-Value Params](docs.md#multiple-value-params)
  * [HTTP Headers](docs.md#http-headers)
* [Responses](docs.md)
  * [Building HTTP responses](docs.md#building-http-responses)
  * [HTTP Redirects](docs.md#redirects)
* [Authentication](docs.md#authentification)
  * [OAuth2](docs.md#authorization-with-oauth2)
  * [Basic Auth](docs.md#basic-http-auth)
* [JSON](docs.md#json)

----

## User Guide

**Step 1:** Define a model (optional):
```scala
case class User(id: Long, name: String)
case class Ticket(id: Long)
```

**Step 2:** Implement REST services:

```scala
import io.finch._
import com.twitter.finagle.Service

case class GetUser(userId: Long) extends Service[HttpRequest, User] {
  def apply(req: HttpRequest) = User(userId, "John").toFuture
}

case class GetTicket(ticketId: Long) extends Service[HttpRequest, Ticket] {
  def apply(req: HttpRequest) = Ticket(ticketId).toFuture
}

case class GetUserTickets(userId: Long) extends Service[HttpRequest, Seq[Ticket]] {
  def apply(req: HttpRequest) = Seq(Ticket(1), Ticket(2), Ticket(3)).toFuture
}
```

**Step 3:** Define filters/services for data transformation (optional):
```scala
import io.finch._
import scala.util.parsing.json.{JSONArray, JSONType, JSONObject}

object TurnModelIntoJson extends Service[Any, JSONType] {
  def apply(req: Any) = {
    def turn(any: Any): JSONType = any match {
      case User(id, name) => JSONObject(Map("id" -> id, "name" -> name))
      case Ticket(id) => JSONObject(Map("id" -> id))
      case seq: Seq[Any] => JSONArray(seq.toList)
    }

    turn(req).toFuture
  }
}
```

**Step 4:** Define endpoints using services/filters for data transformation (optional):
```scala
import io.finch._
import com.twitter.finagle.http.Method
import com.twitter.finagle.http.path._
import scala.util.parsing.json.{JSONArray, JSONObject}

object JsonHelpers {
  implicit def asJson(x: JSONType): Json = new Json {
    override def toString(): String = x.toString()
  }
}

import scala.util.parsing.json.{JSONArray, JSONObject}

object TurnModelIntoJson extends Service[Any, JsonResponse] {
  import JsonHelpers._
  def apply(req: Any) = {
    def turn(any: Any): JsonResponse = any match {
      case User(id, name) => JSONObject(Map("id" -> id, "name" -> name))
      case Ticket(id) => JSONObject(Map("id" -> id))
      case seq: Seq[Any] => JSONArray(seq.toList)
    }

    turn(req).toFuture
  }
}
```

**Step 5:** Expose endpoints:

```scala
import io.finch._
import io.finch.json._
import com.twitter.finagle.builder.ServerBuilder
import com.twitter.finagle.http.{Http, RichHttp}
import java.net.InetSocketAddress

object Main extends App {
  val endpoint = Endpoint.join(User, Ticket) ! JsonResponseConverter ! TurnJsonIntoHttp
  val backend = endpoint orElse Endpoint.NotFound

  ServerBuilder()
    .codec(RichHttp[HttpRequest](Http()))
    .bindTo(new InetSocketAddress(8080))
    .name("user-and-ticket")
    .build(backend.toService)
}
```

## Endpoints

The core operation in Finch.io is _pipe_ `!`. Both requests and responses may be piped via chain of filters, services or endpoints: the data flows in a natural direction - from left to right.

In the following example<commit_msg>remove unnecessary json converter<commit_after># Finch.io Documentation

* [User Guide](docs.md#user-guide)
* [Endpoints](docs.md#endpoints)
* [Requests](docs.md#requests)
  * [Request Reader](docs.md#request-reader-monad)
  * [Multiple-Value Params](docs.md#multiple-value-params)
  * [HTTP Headers](docs.md#http-headers)
* [Responses](docs.md)
  * [Building HTTP responses](docs.md#building-http-responses)
  * [HTTP Redirects](docs.md#redirects)
* [Authentication](docs.md#authentification)
  * [OAuth2](docs.md#authorization-with-oauth2)
  * [Basic Auth](docs.md#basic-http-auth)
* [JSON](docs.md#json)

----

## User Guide

**Step 1:** Define a model (optional):
```scala
case class User(id: Long, name: String)
case class Ticket(id: Long)
```

**Step 2:** Implement REST services:

```scala
import io.finch._
import com.twitter.finagle.Service

case class GetUser(userId: Long) extends Service[HttpRequest, User] {
  def apply(req: HttpRequest) = User(userId, "John").toFuture
}

case class GetTicket(ticketId: Long) extends Service[HttpRequest, Ticket] {
  def apply(req: HttpRequest) = Ticket(ticketId).toFuture
}

case class GetUserTickets(userId: Long) extends Service[HttpRequest, Seq[Ticket]] {
  def apply(req: HttpRequest) = Seq(Ticket(1), Ticket(2), Ticket(3)).toFuture
}
```

**Step 3:** Define filters/services for data transformation (optional):
```scala
import io.finch._
import scala.util.parsing.json.{JSONArray, JSONType, JSONObject}

object TurnModelIntoJson extends Service[Any, JSONType] {
  def apply(req: Any) = {
    def turn(any: Any): JSONType = any match {
      case User(id, name) => JSONObject(Map("id" -> id, "name" -> name))
      case Ticket(id) => JSONObject(Map("id" -> id))
      case seq: Seq[Any] => JSONArray(seq.toList)
    }

    turn(req).toFuture
  }
}
```

**Step 4:** Define endpoints using services/filters for data transformation (optional):
```scala
import io.finch._
import com.twitter.finagle.http.Method
import com.twitter.finagle.http.path._
import scala.util.parsing.json.{JSONArray, JSONObject}

object JsonHelpers {
  implicit def asJson(x: JSONType): Json = new Json {
    override def toString(): String = x.toString()
  }
}

import scala.util.parsing.json.{JSONArray, JSONObject}

object TurnModelIntoJson extends Service[Any, JsonResponse] {
  import JsonHelpers._
  def apply(req: Any) = {
    def turn(any: Any): JsonResponse = any match {
      case User(id, name) => JSONObject(Map("id" -> id, "name" -> name))
      case Ticket(id) => JSONObject(Map("id" -> id))
      case seq: Seq[Any] => JSONArray(seq.toList)
    }

    turn(req).toFuture
  }
}
```

**Step 5:** Expose endpoints:

```scala
import io.finch._
import io.finch.json._
import com.twitter.finagle.builder.ServerBuilder
import com.twitter.finagle.http.{Http, RichHttp}
import java.net.InetSocketAddress

object Main extends App {
  val endpoint = Endpoint.join(User, Ticket) ! TurnJsonIntoHttp
  val backend = endpoint orElse Endpoint.NotFound

  ServerBuilder()
    .codec(RichHttp[HttpRequest](Http()))
    .bindTo(new InetSocketAddress(8080))
    .name("user-and-ticket")
    .build(backend.toService)
}
```

## Endpoints

The core operation in Finch.io is _pipe_ `!`. Both requests and responses may be piped via chain of filters, services or endpoints: the data flows in a natural direction - from left to right.

In the following example
{'fraction_non_alphanumeric': 0.1449511400651466, 'fraction_numerical': 0.00414569144210838, 'mean_word_length': 4.638564273789649, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '838114', 'n_tokens_mistral': 2283, 'n_tokens_neox': 2227, 'n_words': 555}