Git Product home page Git Product logo

plate's Introduction

Plate

Language-agnostic schemas based on Haskell's type system.

Why Schemas

Schema languages like JSON Schema let you to describe data in a way that can be understood by any programming language. They're one of the core components of API description tools like Swagger. Once you write schemas to describe the data your API deals with you can use them to automatically generate documentation, UIs, and client code. This avoids lots of manual, error-prone work at your application boundary.

Why Another Schema Language

Writing a schema language is trickier than it looks. You have to strike a careful balance between over and under-expressiveness.

If you make your schema under-expressive it becomes little better than no schema at all. For example JSchema allows all values described by the schema to be null. While it's easy to find nice things to say about JSchema (such as its simplicity), implicit nulls don't allow enough structure for many tasks.

On the other hand you can error by allowing too much expressiveness. For instance in JSON Schema a clever combination of the "anyOf", "allOf", and "not" keywords is enough to build if and case statements (discovered by Evgeny Poberezkin).

This allows schemas to describe enormously complex structures for which it's impossible to automatically generate clean UIs or client code. Once again this defeats the original purpose. One solution would be to ask schema writers to work in only some subset of the schema langauge, but which subset? We're back to the original problem.

The Idea Behind Plate

The solution is to look for rescue from a related field. Language-specific type system writers have been feeling out the sweet spot of expressiveness longer than the other tools mentioned here have existed. Even better, many of them are battle-hardened and sit on a principled theoretical foundation.

And of course the most glorious, battle-hardened, and principled of these is Haskell. Plate is what you get when you steal the most basic, essential features of Haskell's type system and build a schema language from them. Hopefully this lets Plate strike the right level of expressiveness for many tasks.

Status

Work-in-progress. Nothing is final or production ready. Everything is a mess. Documentation is wrong.

Example

Say we have the following Haskell type:

data Album = Album
  { title  :: Text
  , artist :: Text
  , tracks :: [Text]
  }

We can also express it as a Plate schema using the plate library:

album :: Schema
album = ProductType (HM.fromList
  [ ("title", Builtin SString)
  , ("artist", Builtin SString)
  , ("tracks", Builtin (SSequence (Builtin SString)))
  ])

(It won't be hard to make this conversion automatic, though I haven't gotten around to it yet.)

We can then generate a JSON representation of the schema for other tools to use:

{
  "schema.product": {
    "title": {
      "type": {
        "schema.string": {}
      }
    },
    "artist": {
      "type": {
        "schema.string": {}
      }
    },
    "tracks": {
      "type": {
        "schema.sequence": {
          "type": {
            "schema.string": {}
          }
        }
      }
    }
  }
}

We can also generate UIs so users can conveniently create instances of our schema:

(Note: the editor isn't released yet)

Then say a user creates this piece of data:

{
  "title": "Interstellar: Original Motion Picture Soundtrack",
  "artist": "Hans Zimmer",
  "tracks": {
    "sequence": [
      "Dreaming of the Crash",
      "Cornfield Chase",
      "Dust",
      "Day One",
      "Stay",
      "Message from Home",
      "The Wormhole",
      "Mountains",
      "Afraid of Time",
      "A Place Among the Stars",
      "Running Out",
      "I'm Going Home",
      "Coward",
      "Detach",
      "S.T.A.Y.",
      "Where We're Going"
    ]
  }
}

We can convert it to its Plate representation and then validate it:

λ> Plate.validate mempty albumSchema interstellarSountrack
Right ()

Special Thanks

TJ Weigel created the logo.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.