Skip to content

Basic and advanced JSON decoding and validations in ReScript

Notifications You must be signed in to change notification settings

scoville/re-code

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ReCode

Simple yet powerful JSON parser and validator that relies solely on the built-in Js.Json module. The API is heavily inspired by the Elm Json package, and the Yup library.

The library is well documented and well tested. Using VS Code with the official plugin should show up documentation and examples on function hover.

Screenshot 1

A simple example (Decoder)

Let's pretend we need to parse an incoming JSON that should contain a user object with the following requirements:

  • Should have a positive age
  • Should have a non empty name
  • May have a valid email address
  • Should have a logged in status (boolean)
  • May have a non empty phone number
  • Should have a non empty list of hobbies
  • Should have a date of birth that's a valid date
// Let's define our User module
module User = {
  // It contains the user type
  type t = {
    age: int,
    name: string,
    email: option<string>,
    loggedIn: bool,
    phoneNumber: option<string>,
    hobbies: array<string>,
    dateOfBirth: Js.Date.t,
  }

  // And a convenient `make` function
  let make = (
    age,
    name,
    email,
    loggedIn,
    phoneNumber,
    hobbies,
    dateOfBirth,
  ) => {
    age: age,
    name: name,
    email: email,
    loggedIn: loggedIn,
    phoneNumber: phoneNumber,
    hobbies: hobbies,
    dateOfBirth: dateOfBirth,
  }

  // We can now define our decoder
  let decoder = {
    open Decode
    open DecodeExtra

    pure(make)
    ->Object.required("age", int->Int.min(0))
    ->Object.required("name", string->String.required)
    ->Object.optional("email", string->String.email)
    ->Object.required("loggedIn", bool)
    ->Object.optional("phoneNumber", string->String.required)
    ->Object.required("hobbies", array(string)->Array.notEmpty)
    ->Object.required("dateOfBirth", Date.iso)
  }
}

// We can now validate our incoming payload!
// This example assumes `payload` exists and is a string
switch payload->Decode.decodeString(User.decoder) {
| Ok(user) => Js.log(`User with name ${user.name} is valid!`)
| Error(ParseError) => Js.log("Humm, the JSON was invalid")
| Error(TypeError(error)) => Js.log(`The JSON was valid, but not the value it contained: ${error}`)
}

A simple example (Encoder)

We can also turn complex values into Json:

// Reusing the previous User module and type only
module User = {
  type t = {
    age: int,
    name: string,
    email: option<string>,
    loggedIn: bool,
    phoneNumber: option<string>,
    hobbies: array<string>,
    dateOfBirth: Js.Date.t,
  }
}

let userEncoder = (user: User.t) => {
  open Encode

  object([
    ("age", int(user.age)),
    ("name", string(user.name)),
    ("email", maybe(string, user.email)),
    ("loggedIn", bool(user.loggedIn)),
    ("phoneNumber", maybe(string, user.phoneNumber)),
    ("hobbies", array(string, user.hobbies)),
    ("dateOfBirth", date(user.dateOfBirth)),
  ])
}

// We assume a `myUser` variable exists and has type `User.t`
let json = userEncoder(myUser)

// Let's display our newly created json
Js.log(Js.Json.stringify(json))

See more

You can check the tests for more.

About

Basic and advanced JSON decoding and validations in ReScript

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published