Skip to content

Commit

Permalink
v0.6.0 🚀 - Add Rest.fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
DZakh committed Aug 8, 2024
1 parent e555c05 commit 38fdd7e
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 55 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rescript-rest",
"version": "0.5.0",
"version": "0.6.0",
"description": "😴 ReScript RPC-like client, contract, and server implementation for a pure REST API",
"keywords": [
"rest",
Expand Down
83 changes: 48 additions & 35 deletions src/Rest.res
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,15 @@ 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 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: method,
Expand Down Expand Up @@ -485,41 +493,46 @@ let getCompletePath = (~baseUrl, ~pathItems, ~maybeQuery, ~maybeParams, ~jsonQue
path.contents
}

let client = (~baseUrl, ~fetcher=ApiFetcher.default, ~jsonQuery=false) => {
let call:
type variables response. (route<variables, response>, variables) => promise<response> =
(route, variables) => {
let route = route->(Obj.magic: route<variables, response> => route<unknown, unknown>)
let variables = variables->(Obj.magic: variables => unknown)

let {definition, variablesSchema, responses, pathItems} = route->params

let data = variables->S.serializeToUnknownOrRaiseWith(variablesSchema)->Obj.magic

fetcher({
body: data["body"],
headers: data["headers"],
path: getCompletePath(
~baseUrl,
~pathItems,
~maybeQuery=data["query"],
~maybeParams=data["params"],
~jsonQuery,
),
method: (definition.method :> string),
})->Promise.thenResolve(fetcherResponse => {
switch responses->Response.find(fetcherResponse.status) {
| None =>
panic(
`No registered responses for the status "${fetcherResponse.status->Js.Int.toString}"`,
)
| Some(response) =>
fetcherResponse
->S.parseAnyOrRaiseWith(response.schema)
->(Obj.magic: unknown => response)
}
})
let fetch = (
type variables response,
route: route<variables, response>,
baseUrl,
variables,
~fetcher=ApiFetcher.default,
~jsonQuery=false,
) => {
let route = route->(Obj.magic: route<variables, response> => route<unknown, unknown>)
let variables = variables->(Obj.magic: variables => unknown)

let {definition, variablesSchema, responses, pathItems} = route->params

let data = variables->S.serializeToUnknownOrRaiseWith(variablesSchema)->Obj.magic

fetcher({
body: data["body"],
headers: data["headers"],
path: getCompletePath(
~baseUrl,
~pathItems,
~maybeQuery=data["query"],
~maybeParams=data["params"],
~jsonQuery,
),
method: (definition.method :> string),
})->Promise.thenResolve(fetcherResponse => {
switch responses->Response.find(fetcherResponse.status) {
| None =>
panic(`No registered responses for the status "${fetcherResponse.status->Js.Int.toString}"`)
| Some(response) =>
fetcherResponse
->S.parseAnyOrRaiseWith(response.schema)
->(Obj.magic: unknown => response)
}
})
}

let client = (~baseUrl, ~fetcher=ApiFetcher.default, ~jsonQuery=false) => {
let call = (route, variables) => route->fetch(baseUrl, variables, ~fetcher, ~jsonQuery)
{
baseUrl,
fetcher,
Expand Down
41 changes: 24 additions & 17 deletions src/Rest.res.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/Rest.resi
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,11 @@ type client = {
}

let client: (~baseUrl: string, ~fetcher: ApiFetcher.t=?, ~jsonQuery: bool=?) => client

let fetch: (
route<'variables, 'response>,
string,
'variables,
~fetcher: ApiFetcher.t=?,
~jsonQuery: bool=?,
) => promise<'response>

0 comments on commit 38fdd7e

Please sign in to comment.