rescript-schema-ppx
v8.4.0
Published
ReScript PPX to generate rescript-schema from type
Downloads
399
Readme
ReScript Schema PPX
ReScript PPX to generate rescript-schema from type.
🧠 It's 100% opt-in. You can use rescript-schema without ppx.
Table of contents
Install
npm install rescript-schema rescript-schema-ppx
Then update your rescript.json
config:
{
...
+ "bs-dependencies": ["rescript-schema"],
+ "bsc-flags": ["-open RescriptSchema"],
+ "ppx-flags": ["rescript-schema-ppx/bin"],
}
Basic usage
// 1. Define a type and add @schema attribute
@schema
type rating =
| @as("G") GeneralAudiences
| @as("PG") ParentalGuidanceSuggested
| @as("PG13") ParentalStronglyCautioned
| @as("R") Restricted
@schema
type film = {
@as("Id")
id: float,
@as("Title")
title: string,
@as("Tags")
tags: @s.default([]) array<string>,
@as("Rating")
rating: rating,
@as("Age")
deprecatedAgeRestriction: @s.deprecate("Use rating instead") option<int>,
}
// 2. Generated by PPX ⬇️
let ratingSchema = S.union([
S.literal(GeneralAudiences),
S.literal(ParentalGuidanceSuggested),
S.literal(ParentalStronglyCautioned),
S.literal(Restricted),
])
let filmSchema = S.object(s => {
id: s.field("Id", S.float),
title: s.field("Title", S.string),
tags: s.fieldOr("Tags", S.array(S.string), []),
rating: s.field("Rating", ratingSchema),
deprecatedAgeRestriction: s.field("Age", S.option(S.int)->S.deprecate("Use rating instead")),
})
// 3. Parse data using the schema
// The data is validated and transformed to a convenient format
%raw(`{
"Id": 1,
"Title": "My first film",
"Rating": "R",
"Age": 17
}`)->S.parseWith(filmSchema)
// Ok({
// id: 1.,
// title: "My first film",
// tags: [],
// rating: Restricted,
// deprecatedAgeRestriction: Some(17),
// })
// 4. Transform data back using the same schema
{
id: 2.,
tags: ["Loved"],
title: "Sad & sed",
rating: ParentalStronglyCautioned,
deprecatedAgeRestriction: None,
}->S.serializeWith(filmSchema)
// Ok(%raw(`{
// "Id": 2,
// "Title": "Sad & sed",
// "Rating": "PG13",
// "Tags": ["Loved"],
// "Age": undefined,
// }`))
// 5. Use schema as a building block for other tools
// For example, create a JSON-schema with rescript-json-schema and use it for OpenAPI generation
let filmJSONSchema = JSONSchema.make(filmSchema)
🧠 Read more about schema usage in the ReScript Schema for ReScript users documentation.
API reference
@schema
Applies to: type declarations, type signatures
Indicates that a schema should be generated for the given type.
@s.matches(S.t<'value>)
Applies to: type expressions
Specifies custom schema for the type.
@schema
type t = @s.matches(S.string->S.url) string
// Generated by PPX ⬇️
let schema = S.string->S.url
@s.null
Applies to: option type expressions
Tells to use S.null
for the option schema constructor.
@schema
type t = @s.null option<string>
// Generated by PPX ⬇️
let schema = S.null(S.string)
@s.nullable
Applies to: option type expressions
Tells to use S.nullable
for the option schema constructor.
@schema
type t = @s.nullable option<string>
// Generated by PPX ⬇️
let schema = S.nullable(S.string)
@s.default('value)
Applies to: type expressions
Wraps the type expression schema into an option with the provided default value.
@schema
type t = @s.default("Unknown") string
// Generated by PPX ⬇️
let schema = S.option(S.string)->S.Option.getOr("Unknown")
It might be used together with @s.null
or @s.nullable
:
@schema
type t = @s.nullable @s.default("Unknown") string
// Generated by PPX ⬇️
let schema = S.nullable(S.string)->S.Option.getOr("Unknown")
@s.defaultWith(unit => 'value)
Applies to: type expressions
Wraps the type expression schema into an option with callback to get the default value.
@schema
type t = @s.defaultWith(() => []) array<string>
// Generated by PPX ⬇️
let schema = S.option(S.array(S.string))->S.Option.getOrWith(() => [])
🧠 The same as
@s.default
it might be used together with@s.null
or@s.nullable
@s.describe(string)
Applies to: type expressions
Adds description
property to the generated schema.
@schema
type t = @s.describe("A useful bit of text, if you know what to do with it.") string
// Generated by PPX ⬇️
let schema = S.string->S.describe("A useful bit of text, if you know what to do with it.")
This can be useful for documenting a field, for example in a JSON Schema using a library like rescript-json-schema
.
@s.deprecate(string)
Applies to: type expressions
Adds deprecation
property to the generated schema.
@schema
type t = @s.deprecate("Will be removed in APIv2") string
// Generated by PPX ⬇️
let schema = S.string->S.deprecate("Will be removed in APIv2")
This can be useful for documenting a field, for example in a JSON Schema using a library like rescript-json-schema
.