Skip to content

Commit

Permalink
Feature: Headers composition (zio#667)
Browse files Browse the repository at this point in the history
* refactor: remove "Header" use "Header(s)" instead everywhere

* refactor: header usage inside the examples

* refactor: add combinators for Headers

* refactor: update helpers in Http

* refactor: update helpers in Patch

* refactor: update helpers in Request, Response

* refactor: update test to use Headers

* refactor: update service usage of Headers

* refactor: update usage of header in Middleware

* refactor: headers and headerextensions

* scalafmt changes

* refactor: remove HeaderExtension.Only

* refactor: add Header type alias back to reduce diff produced

* refactor: fix header spec

* refactor: fix header and middleware spec

* refactor: reorder tests in MiddlewareSpec

* feature: add HeaderName and HeaderValue

* feature: add tuples of headers

* refactor: use chunk to hold Headers

* refactor: add helpers in Headers with builder-pattern

* refactor: Headers is now backed by Chunk

* refactor: improve header spec

* refactor: move names to Headers

* refactor: update examples

* refactor: rename object

* refactor: update constructors and usages

* refactor: split header.scala into smaller more maintainable files

* refactor: clean up

* style: scalafmt

* scalafmt fixes

* refactor: update constraint requirements

* refactor: rename methods and name alias

* refactor: rename files

* refactor: fix for jdk 8

* scalafmt fixes

* refactor: add support for Cookie for Headers.cookie

* chore: update fmt settings to use the later scalafmt config for sorted imports

* scalafmt fixes

* test: update header spec

* fix: Response.text content-type

* refactor: remove duplicate cookie getters

* refactor: restructure header code
  • Loading branch information
Tushar Mathur authored Dec 22, 2021
1 parent ce9afac commit 9c84756
Show file tree
Hide file tree
Showing 41 changed files with 1,468 additions and 736 deletions.
4 changes: 3 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ includeCurlyBraceInSelectChains = false
spaces.inImportCurlyBraces = false
optIn.annotationNewlines = true

rewrite.rules = [SortImports, RedundantBraces, SortModifiers]
rewrite.rules = [Imports, RedundantBraces, SortModifiers]
rewrite.imports.sort = original

docstrings.wrap = yes
docstrings.style = Asterisk

Expand Down
2 changes: 1 addition & 1 deletion example/src/main/scala/example/Authentication.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ object Authentication extends App {
Http
.fromFunction[Request] {
_.getHeader("X-ACCESS-TOKEN")
.flatMap(header => jwtDecode(header.value.toString))
.flatMap(header => jwtDecode(header._2.toString))
.fold[HttpApp[R, E]](fail)(success)
}
.flatten
Expand Down
2 changes: 1 addition & 1 deletion example/src/main/scala/example/HelloWorld.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ object HelloWorld extends App {
// Create HTTP route
val app: HttpApp[Any, Nothing] = Http.collect[Request] {
case Method.GET -> !! / "text" => Response.text("Hello World!")
case Method.GET -> !! / "json" => Response.jsonString("""{"greetings": "Hello World!"}""")
case Method.GET -> !! / "json" => Response.json("""{"greetings": "Hello World!"}""")
}

// Run it like any simple app
Expand Down
17 changes: 9 additions & 8 deletions example/src/main/scala/example/HelloWorldTwirl.scala
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
package example

import zhttp.endpoint._
import zhttp.http.Headers.Literals._
import zhttp.http.Method.GET
import zhttp.http._
import zhttp.nav.Navigation
import zhttp.service.Server
import zio.{ExitCode, URIO}

object HelloWorldTwirl extends zio.App {
def app: HttpApp[Any, Throwable] = h1 ++ h2

def h2: HttpApp[Any, Nothing] = GET / "a" / *[Int] / "b" / *[Boolean] to { pathParams =>
val (a, b) = pathParams.params
val response: UResponse = Response.text(advanced.html.index(a, b).toString())
response
.copy(headers = List(Header.custom("content-type", "text/html")))
.copy(headers = Headers(Name.ContentType, Value.TextHtml))
}

override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] =
Server.start(8090, app).exitCode

val h1: HttpApp[Any, Nothing] = Http.collect[Request] {
case Method.GET -> !! =>
Response.text(html.index("John Doe").toString()).addHeader(Header.contentTypeHtml)
Response.text(html.index("John Doe").toString()).addHeader(Name.ContentType, Value.TextHtml)
case Method.GET -> !! / "nav" => {
val nav = Seq(
Navigation("link-1", "http://google.com", Some("bi-alarm-fill")),
Expand All @@ -34,12 +40,7 @@ object HelloWorldTwirl extends zio.App {
),
),
)
Response.text(advanced.html.template(1, false, nav).toString()).addHeader(Header.contentTypeHtml)
Response.text(advanced.html.template(1, false, nav).toString()).addHeader(Name.ContentType, Value.TextHtml)
}
}

def app: HttpApp[Any, Throwable] = h1 ++ h2

override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] =
Server.start(8090, app).exitCode
}
2 changes: 1 addition & 1 deletion example/src/main/scala/example/HelloWorldWithCORS.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ object HelloWorldWithCORS extends App {
val app: HttpApp[Any, Nothing] =
Http.collect[Request] {
case Method.GET -> !! / "text" => Response.text("Hello World!")
case Method.GET -> !! / "json" => Response.jsonString("""{"greetings": "Hello World!"}""")
case Method.GET -> !! / "json" => Response.json("""{"greetings": "Hello World!"}""")
} @@ cors(config)

// Run it like any simple app
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package example

import zhttp.http.Middleware.{addHeader, debug, patchM, timeout}
import zhttp.http.{Header, HttpApp, Method, Patch, Response, _}
import zhttp.http._
import zhttp.service.Server
import zio.clock.{Clock, currentTime}
import zio.console.Console
Expand All @@ -23,7 +23,7 @@ object HelloWorldWithMiddlewares extends App {
val serverTime: Middleware[Clock, Nothing] = patchM((_, _) =>
for {
currentMilliseconds <- currentTime(TimeUnit.MILLISECONDS)
withHeader = Patch.addHeaders(List(Header("X-Time", currentMilliseconds.toString)))
withHeader = Patch.addHeader("X-Time", currentMilliseconds.toString)
} yield withHeader,
)

Expand Down
4 changes: 2 additions & 2 deletions example/src/main/scala/example/HttpsClient.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package example

import io.netty.handler.ssl.SslContextBuilder
import zhttp.http.Header
import zhttp.http.Headers
import zhttp.service.client.ClientSSLHandler.ClientSSLOptions
import zhttp.service.{ChannelFactory, Client, EventLoopGroup}
import zio.{App, ExitCode, URIO, console}
Expand All @@ -13,7 +13,7 @@ import javax.net.ssl.TrustManagerFactory
object HttpsClient extends App {
val env = ChannelFactory.auto ++ EventLoopGroup.auto()
val url = "https://sports.api.decathlon.com/groups/water-aerobics"
val headers = List(Header.host("sports.api.decathlon.com"))
val headers = Headers.host("sports.api.decathlon.com")

// Configuring Truststore for https(optional)
val trustStore: KeyStore = KeyStore.getInstance("JKS")
Expand Down
2 changes: 1 addition & 1 deletion example/src/main/scala/example/HttpsHelloWorld.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object HttpsHelloWorld extends App {
// Create HTTP route
val app: HttpApp[Any, Nothing] = Http.collect[Request] {
case Method.GET -> !! / "text" => Response.text("Hello World!")
case Method.GET -> !! / "json" => Response.jsonString("""{"greetings": "Hello World!"}""")
case Method.GET -> !! / "json" => Response.json("""{"greetings": "Hello World!"}""")
}

/**
Expand Down
4 changes: 2 additions & 2 deletions example/src/main/scala/example/SimpleClient.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package example

import zhttp.http.Header
import zhttp.http.Headers
import zhttp.service.{ChannelFactory, Client, EventLoopGroup}
import zio.{App, ExitCode, URIO, console}

object SimpleClient extends App {
val env = ChannelFactory.auto ++ EventLoopGroup.auto()
val url = "http://sports.api.decathlon.com/groups/water-aerobics"
val headers = List(Header.host("sports.api.decathlon.com"))
val headers = Headers.host("sports.api.decathlon.com")

val program = for {
res <- Client.request(url, headers)
Expand Down
17 changes: 8 additions & 9 deletions example/src/main/scala/example/StreamingResponse.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ import zio.{App, Chunk, ExitCode, URIO}
* Example to encode content using a ZStream
*/
object StreamingResponse extends App {
// Create a message as a Chunk[Byte]
val message = Chunk.fromArray("Hello world !\r\n".getBytes(HTTP_CHARSET))
override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] = {

// Starting the server (for more advanced startup configuration checkout `HelloWorldAdvanced`)
Server.start(8090, app.silent).exitCode
}

// Create a message as a Chunk[Byte]
val message = Chunk.fromArray("Hello world !\r\n".getBytes(HTTP_CHARSET))
// Use `Http.collect` to match on route
val app: HttpApp[Any, Nothing] = Http.collect[Request] {

Expand All @@ -22,14 +27,8 @@ object StreamingResponse extends App {
case Method.GET -> !! / "stream" =>
Response(
status = Status.OK,
headers = List(Header.contentLength(message.length.toLong)),
headers = Headers.contentLength(message.length.toLong),
data = HttpData.fromStream(ZStream.fromChunk(message)), // Encoding content using a ZStream
)

}
override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] = {

// Starting the server (for more advanced startup configuration checkout `HelloWorldAdvanced`)
Server.start(8090, app.silent).exitCode
}
}
34 changes: 0 additions & 34 deletions zio-http/src/main/scala/zhttp/http/HasCookie.scala

This file was deleted.

93 changes: 0 additions & 93 deletions zio-http/src/main/scala/zhttp/http/Header.scala

This file was deleted.

Loading

0 comments on commit 9c84756

Please sign in to comment.