I found it to be a HUGE win to communicate between a web apps frontend and backend using ordinary variants. So far I haven’t encountered any problems, but I’m wondering if there could be any issues.
Here’s the types (note this is ALL possible responses from server side currently, whether its scalable I haven’t decided yet)
type authType = Success | Fail | Invalid | Needed | Ended | Active | Inactive
type errorType = NotFound
type dataType = Bookmarks(array<Bookmarks.t>)
type createType = Duplicate | Success
type recoverType = Sent | NotFound | Reset | BadToken | TooShort
@tag("state")
type t =
| Auth(authType)
| Error(errorType)
| Data(dataType)
| Create(createType)
| Recover(recoverType)
| Init
| Loading
Here’s the server responding with some bookmark data. This is just basic express, which I’m assuming just serializes with JSON.stringify
res->Express5.sendResponse(Data(Bookmarks(bookmarks)))
Here is the client getting the data. You can see the rescript goodness is where we can directly switch on the response.
let response = await Responses.fetchGet("/backend/bookmarks")
let bookmarks = switch response {
| Data(Bookmarks(bms)) => bms
| _ => Responses.raiseError(response) // didnt get response we expected
}
Here is Responses.fetchGet()
let fetchGet = async (url: string): t => {
open Fetch
let args: Request.init = {
method: #GET,
headers: Headers.fromObject({"Content-type": "application/json"}),
}
let response = await fetch(url, args)
let response = await response->Response.json
let response = response->jsonTot
response
}
Here’s the cheat code that makes this all possible without having to validate anything
external jsonTot: JSON.t => t = "%identity"
If you are wondering I’m not that concerned with validating because I would be validating a variant I just requested that was created from the exact same source. I’m not expecting a man-in-the-middle attack breaking my serialized variants.
I’m also very curious if the internal representation of the variant would be stable enough to generate it from another language, like a golang backend.
Here is what it looks like with empty data FYI, looks a little “undocumented” to me
{"state":"Data","_0":{"TAG":"Bookmarks","_0":[]}}