diff --git a/README.md b/README.md index 5c0ec01..c2eb888 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Easily define your API contract somewhere shared, for example, `Contract.res`: ```rescript let createPost = Rest.route(() => { path: "/posts", - method: "POST", + method: Post, variables: s => { "title": s.field("title", S.string), "body": s.field("body", S.string), @@ -57,7 +57,7 @@ let createPost = Rest.route(() => { let getPosts = Rest.route(() => { path: "/posts", - method: "GET", + method: Get, variables: s => { "skip": s.query("skip", S.int), "take": s.query("take", S.int), @@ -114,7 +114,7 @@ You can define path parameters by adding them to the `path` strin with a curly b ```rescript let getPost = Rest.route(() => { path: "/api/author/{authorId}/posts/{id}", - method: "GET", + method: Get, variables: s => { "authorId": s.param("authorId", S.string->S.uuid), "id": s.param("id", S.int), @@ -142,7 +142,7 @@ You can add query parameters to the request by using the `s.query` method in the ```rescript let getPosts = Rest.route(() => { path: "/posts", - method: "GET", + method: Get, variables: s => { "skip": s.query("skip", S.int), "take": s.query("take", S.int), @@ -170,7 +170,7 @@ You can add headers to the request by using the `s.header` method in the `variab ```rescript let getPosts = Rest.route(() => { path: "/posts", - method: "GET", + method: Get, variables: s => { "authorization": s.header("authorization", S.string), "pagination": s.header("pagination", S.option(S.int)), @@ -188,7 +188,7 @@ Responses are described as an array of response definitions. It's possible to as ```rescript let createPost = Rest.route(() => { path: "/posts", - method: "POST", + method: Post, variables: _ => (), responses: [ s => { @@ -208,7 +208,7 @@ You can use `s.status` multiple times. To define a range of response statuses, y ```rescript let createPost = Rest.route(() => { path: "/posts", - method: "POST", + method: Post, variables: _ => (), responses: [ s => { @@ -245,7 +245,7 @@ You can define custom headers in a response as follows: ```rescript let ping = Rest.route(() => { path: "/ping", - method: "GET", + method: Get, summary: "Checks if the server is alive", variables: _ => (), responses: [ diff --git a/__tests__/Rest_path_test.res b/__tests__/Rest_path_test.res index 513623a..eba5f81 100644 --- a/__tests__/Rest_path_test.res +++ b/__tests__/Rest_path_test.res @@ -12,7 +12,7 @@ asyncTest("Fails with path parameter not defined in variables", async t => { let createGame = Rest.route(() => { path: "/game/{gameId}", - method: "POST", + method: Post, variables: _ => (), responses: [ s => { @@ -37,7 +37,7 @@ asyncTest("Fails with path parameter not defined in the path string", async t => let createGame = Rest.route(() => { path: "/game", - method: "POST", + method: Post, variables: s => s.param("gameId", S.string), responses: [ s => { @@ -62,7 +62,7 @@ asyncTest("Fails with empty path parameter name", async t => { let createGame = Rest.route(() => { path: "/game/{}", - method: "POST", + method: Post, variables: s => s.param("", S.string), responses: [ s => { @@ -87,7 +87,7 @@ asyncTest("Fails with path parameter missing closing curly bracket", async t => let createGame = Rest.route(() => { path: "/game/{gameId", - method: "POST", + method: Post, variables: s => s.param("", S.string), responses: [ s => { @@ -112,7 +112,7 @@ asyncTest("Fails with path parameter missing opening curly bracket", async t => let createGame = Rest.route(() => { path: "/game/gameId}", - method: "POST", + method: Post, variables: s => s.param("gameId", S.string), responses: [ s => { @@ -137,7 +137,7 @@ asyncTest("Fails with path parameter switched open and close curly bracket", asy let createGame = Rest.route(() => { path: "/game/}gameId{", - method: "POST", + method: Post, variables: s => s.param("gameId", S.string), responses: [ s => { diff --git a/__tests__/Rest_test.res b/__tests__/Rest_test.res index fcc1f73..f0eed61 100644 --- a/__tests__/Rest_test.res +++ b/__tests__/Rest_test.res @@ -25,7 +25,7 @@ asyncTest("Test simple POST request", async t => { let createGame = Rest.route(() => { path: "/game", - method: "POST", + method: Post, variables: s => s.body(userSchema), responses: [ s => { @@ -62,7 +62,7 @@ asyncTest("Test request with mixed body and header data", async t => { let createGame = Rest.route(() => { path: "/game", - method: "POST", + method: Post, variables: s => { "userName": s.field("user_name", S.string), @@ -105,7 +105,7 @@ asyncTest("Test simple GET request", async t => { let getHeight = Rest.route(() => { path: "/height", - method: "GET", + method: Get, variables: _ => (), responses: [ s => { @@ -123,7 +123,7 @@ asyncTest("Test simple GET request", async t => { asyncTest("Test query params encoding to path", async t => { let getHeight = Rest.route(() => { path: "/height", - method: "GET", + method: Get, variables: s => { "string": s.query("string", S.string), @@ -263,7 +263,7 @@ asyncTest("Example test", async t => { let createPost = Rest.route(() => { path: "/posts", - method: "POST", + method: Post, variables: s => { "title": s.field("title", S.string), @@ -279,7 +279,7 @@ asyncTest("Example test", async t => { let getPosts = Rest.route(() => { path: "/posts", - method: "GET", + method: Get, variables: s => { "skip": s.query("skip", S.int), @@ -352,7 +352,7 @@ asyncTest("Multiple path params", async t => { let getSubComment = Rest.route(() => { path: "/post/{id}/comments/{commentId}/{commentId2}", - method: "GET", + method: Get, variables: s => { "id": s.param("id", S.string), @@ -392,7 +392,7 @@ asyncTest("Fails to register two default responses", async t => { let getHeight = Rest.route(() => { path: "/height", - method: "GET", + method: Get, variables: _ => (), responses: [ s => { @@ -424,7 +424,7 @@ asyncTest("Fails when response is not registered", async t => { let getHeight = Rest.route(() => { path: "/height", - method: "GET", + method: Get, variables: _ => (), responses: [], }) @@ -447,7 +447,7 @@ asyncTest("Uses default response when explicit status is not defined", async t = let getHeight = Rest.route(() => { path: "/height", - method: "GET", + method: Get, variables: _ => (), responses: [ s => { @@ -473,7 +473,7 @@ asyncTest("Uses 2XX response when explicit status is not defined", async t => { let getHeight = Rest.route(() => { path: "/height", - method: "GET", + method: Get, variables: _ => (), responses: [ s => { @@ -500,7 +500,7 @@ asyncTest("Fails with an invalid response data", async t => { let getHeight = Rest.route(() => { path: "/height", - method: "GET", + method: Get, variables: _ => (), responses: [ s => { diff --git a/src/Rest.res b/src/Rest.res index 27575e2..2fa846e 100644 --- a/src/Rest.res +++ b/src/Rest.res @@ -251,8 +251,10 @@ type s = { param: 'value. (string, S.t<'value>) => 'value, } +type method = |@as("GET") Get | @as("POST") Post | @as("PUT") Put | @as("PATCH") Patch | @as("DELETE") Delete | @as("HEAD") Head | @as("OPTIONS") Options | @as("TRACE") Trace + type definition<'variables, 'response> = { - method: string, + method: method, path: string, variables: s => 'variables, responses: array 'response>, @@ -504,7 +506,7 @@ let client = (~baseUrl, ~fetcher=ApiFetcher.default, ~jsonQuery=false) => { ~maybeParams=data["params"], ~jsonQuery, ), - method: definition.method, + method: (definition.method :> string), })->Promise.thenResolve(fetcherResponse => { switch responses->Response.find(fetcherResponse.status) { | None => diff --git a/src/Rest.resi b/src/Rest.resi index 011e1a8..804b425 100644 --- a/src/Rest.resi +++ b/src/Rest.resi @@ -100,8 +100,18 @@ type s = { param: 'value. (string, S.t<'value>) => 'value, } +type method = + | @as("GET") Get + | @as("POST") Post + | @as("PUT") Put + | @as("PATCH") Patch + | @as("DELETE") Delete + | @as("HEAD") Head + | @as("OPTIONS") Options + | @as("TRACE") Trace + type definition<'variables, 'response> = { - method: string, + method: method, path: string, variables: s => 'variables, responses: array 'response>,