@@ -1,5 +1,114 @@
11[The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md)
22
3+Package versions follow the [Package Versioning Policy](https://pvp.haskell.org/): in A.B.C, bumps to either A or B represent major versions.
4+
5+0.19
6+----
7+
8+### Significant changes
9+
10+- Drop support for GHC < 8.6.
11+- Support GHC 9.0 (GHC 9.2 should work as well, but isn't fully tested yet).
12+- Support Aeson 2 ([#1475](https://github.com/haskell-servant/servant/pull/1475)).
13+- Add `NamedRoutes` combinator, making support for records first-class in Servant
14+ ([#1388](https://github.com/haskell-servant/servant/pull/1388)).
15+
16+ Users can now directly mark part as an API as defined by a record, instead of
17+ using `(:<|>)` to combine routes. Concretely, the anonymous:
18+
19+ ```haskell
20+ type API =
21+ "version" :> Get '[JSON] String :<|>
22+ "products" :> Get '[JSON] [Product]
23+ ```
24+
25+ can be replaced with the explicitly-named:
26+
27+ ```haskell
28+ type API = NamedRoutes NamedAPI
29+ data NamedAPI mode = NamedAPI
30+ { version :: mode :- "version" :> Get '[JSON] String
31+ , products :: mode :- "products" :> Get '[JSON] [Product]
32+ }
33+ ```
34+
35+ `NamedRoutes` builds upon `servant-generic`, but improves usability by freeing
36+ users from the need to perform `toServant` / `fromServant` conversions
37+ manually. Serving `NamedRoutes NamedAPI` is now done directly by providing a
38+ record of handlers, and servant generates clients directly as records as well.
39+ In particular, it makes it much more practical to work with nested hierarchies
40+ of named routes.
41+
42+ Two convenience functions, `(//)` and `(/:)`, have been added to make the
43+ usage of named route hierarchies more pleasant:
44+
45+ ```haskell
46+ rootClient :: RootApi (AsClientT ClientM)
47+ rootClient = client (Proxy @API)
48+
49+ hello :: String -> ClientM String
50+ hello name = rootClient // hello /: name
51+
52+ endpointClient :: ClientM Person
53+ endpointClient = client // subApi /: "foobar123" // endpoint
54+
55+ type Api = NamedRoutes RootApi
56+
57+ data RootApi mode = RootApi
58+ { subApi :: mode :- Capture "token" String :> NamedRoutes SubApi
59+ , hello :: mode :- Capture "name" String :> Get '[JSON] String
60+ , …
61+ } deriving Generic
62+
63+ data SubApi mode = SubApi
64+ { endpoint :: mode :- Get '[JSON] Person
65+ , …
66+ } deriving Generic
67+ ```
68+
69+- Add custom type errors for partially applied combinators
70+ ([#1289](https://github.com/haskell-servant/servant/pull/1289),
71+ [#1486](https://github.com/haskell-servant/servant/pull/1486)).
72+
73+ For example, forgetting to document the expected type for a query parameter,
74+ as in:
75+
76+ ``` haskell
77+ type API = QueryParam "param" :> Get '[JSON] NoContent
78+ ```
79+
80+ will raise to the following error when trying to serve the API:
81+
82+ ```
83+ • There is no instance for HasServer (QueryParam'
84+ '[Optional, Strict] "param" :> ...)
85+ QueryParam' '[Optional, Strict] "1" expects 1 more arguments
86+ ```
87+
88+ As a consequence of this change, unsaturated types are now forbidden before `(:>)`.
89+
90+- Add a `HeadNoContent` verb ([#1502](https://github.com/haskell-servant/servant/pull/1502)).
91+
92+- *servant-client* / *servant-client*: Fix erroneous behavior, where only 2XX
93+ status codes would be considered successful, irrelevant of the status
94+ parameter specified by the verb combinator.
95+ ([#1469](https://github.com/haskell-servant/servant/pull/1469))
96+
97+- *servant-client* / *servant-client-core*: Fix `Show` instance for
98+ `Servant.Client.Core.Request`.
99+
100+
101+- *servant-client* / *servant-client-core*: Allow passing arbitrary binary data
102+ in Query parameters.
103+ ([#1432](https://github.com/haskell-servant/servant/pull/1432)).
104+
105+### Other changes
106+
107+- Various bit rotten cookbooks have been updated and re-introduced on
108+ `haskell-servant.github.io`.
109+
110+- Various version bumps.
111+
31120.18.3
4113------
5114