I’ve made something quite similar, with a friendly hashtag syntax, that live updates into React PropTypes, Mongoose, Swift, Elm, Golang and more — https://schema.lofi.design/
Planning on adding TypeScript soon, and may do JSONSchema too!
Yes, I’m trying to make something very user friendly, something that designers and product managers and junior developers could use with ease. I plan on adding a validator so that any mistakes are caught.
Amazing. I was dreaming about writing a library to do exactly this during Ludum Dare this weekend (I want strongly typed access to my tilemaps), and here I find it on HN the next day. :)
Awesome work. Expressing concepts that TS's type system can't handle (eg. minimum) as comments is an approach that I didn't consider. So far I've been focused on the idea of generating decorators [0], but comments seem like a solid stopgap. Especially because they show up as tooltips in VSCode.
Yes! Fantastic. Typescript interfaces are a great way to specify JSON schemas, much friendlier than eg JSON Schema and the likes.
Now that TypeScript is gaining traction it might be a great moment to start documenting your REST payloads with it instead of eg JSON Schema or just some JSON example blobs. It's very readable even for non TypeScript programmers.
You can use OpenAPI/swagger to do that, which contains a subset of Json Schema, you have the option to use Yaml instead of json notation and have it language-independent and with the option to generate client and server code for multiple languages.
Funny this comes up today. Right now I'm looking into how I can do pretty much the exact opposite - take our Flow types and convert them to JSONSchema (or anything else) that lets me validate an object against the type at runtime.
It's quite trivial for a static analyzer to distinguish between a "string" and numeric value. So I think it's unnecessary to annotate : string : number, etc it just adds noise to the code. If you want to catch real bugs, check the parameters!
Just a question.
How does JSON and JSONSchema deal with graph structure?
For example, what happens when your data structure in memory is A->B->C->A. And you want to serialize/deserialize such a data structure.
(as far as i undestand, the JSON serialization of this graph would have duplicated A, once a top level and once inside the serialization of C).
You can probably encode a directed graph by storing the nodes as values in a dictionary which track which nodes they point too, and the keys of the dictionary would be the node identifiers. If you represent it a specific way in your program, just perform a normalisation phase after decoding, and vice versa for encoding.
As far as I understand, this is the way RDF works.
I use N3.js and it basically does that.
Is it a need that usually appears when you send JSON between server and client?
JSONSchema has a concept of "$refs", which is a way to encode a pointer to a value in a JSONSchema. $refs can point to another node in the same graph, a node in another JSONSchema on the same filesystem, or a node in another JSONSchema fetched over the network.
$refs are used in JSONSchema, but are described in the separate JSONPointer spec [0].
I'm not the author, but I assume the intent is to allow you to share the JSONSchema definition between the front-end and back-end. For example, a developer could write an annotated .NET class using the Json.NET schema library from Newtonsoft[1], automatically generate the schema for that class, then use this project to compile that schema into an equivalent TypeScript class. Or go the other way around (TypeScript -> JSONSchema -> .NET class). Or start from the middle with a JSONSchema.
Alone, you're right, this project doesn't make much sense, but it's part of a larger community of tools for creating cross-language model definitions based on a common schema language.
TypeScript doesn't produce any runtime code for validating types - this is good for data inputs from untrusted sources where you want to type in TypeScript at compile-time but still validate against the schema at runtime.
Almost all of our service endpoints were designed API-first with JSON Schema and AJV validation. I could see this being useful for us to get TS models generated quickly for the UI team rather than hand-coding them for all of our existing schemas during our move to using TS/Angular.
For any use case where there is a set of servers and a set of clients that interact with those servers, you often end up having to hard-code API contracts and response shapes on each client and each server.
If your client and server are written in the same language, you might be able to write an interface/class once and share the code between both builds. But what if (as is more often the case) they are written in different languages? What if you introduce a 3rd client, written in a 3rd language (say C# on the server, Swift on iOS, and Java on Android)?
This is what Google uses Protobuf for [0]. A competing solution is JSONSchema, which gives a slightly different set of functionality than Protobuf.
You describe your interface once with JSONSchema, and compile it into interfaces/classes for your various clients/servers to consume. This gives you compile time safety, and eliminates the need to manually author these classes and manually keep them in sync between platforms.
As you scale up the number of services/clients/servers you're running, a system like this becomes not just helpful, but necessary to ensure that they can all talk to one another.
We've gotten to a point where a human-readable, human-editable text format
for structured data has become a complex nightmare where somebody can safely
say "As many threads on xml-dev have shown, text-based processing of XML is
hazardous at best" and be perfectly valid in saying it.
-- Tom Bradford
35 comments
[ 5.0 ms ] story [ 103 ms ] threadPlanning on adding TypeScript soon, and may do JSONSchema too!
It’s written in Elm, whose strict compiler really helps with avoiding bugs. https://github.com/RoyalIcing/lofi-schema-elm
I'm considering taking a crack at a Julia output module for your project. Those output adapters look pretty straightforward.
Ok will consider JSON Schema support. Thanks!
In case you need to do the reverse, for example model-first in typescript and want to generate JSONSchema:
Typescript Code to JSONSchema: https://github.com/YousefED/typescript-json-schema - started this long ago but some great contributors are leading it since!
[0] https://github.com/bcherny/json-schema-to-typescript/issues/...
Now that TypeScript is gaining traction it might be a great moment to start documenting your REST payloads with it instead of eg JSON Schema or just some JSON example blobs. It's very readable even for non TypeScript programmers.
https://docs.oracle.com/javase/7/docs/technotes/tools/share/...
$refs are used in JSONSchema, but are described in the separate JSONPointer spec [0].
See unit tests for examples:
- In-file $ref: https://github.com/bcherny/json-schema-to-typescript/blob/ma...
- Local $ref: https://github.com/bcherny/json-schema-to-typescript/blob/ma...
- Remote $ref: https://github.com/bcherny/json-schema-to-typescript/blob/ma...
- Cyclical $ref: https://github.com/bcherny/json-schema-to-typescript/blob/ma...
Hope that helps!
[0] https://tools.ietf.org/html/rfc6901
Alone, you're right, this project doesn't make much sense, but it's part of a larger community of tools for creating cross-language model definitions based on a common schema language.
[1] : http://www.newtonsoft.com/jsonschema
For any use case where there is a set of servers and a set of clients that interact with those servers, you often end up having to hard-code API contracts and response shapes on each client and each server.
If your client and server are written in the same language, you might be able to write an interface/class once and share the code between both builds. But what if (as is more often the case) they are written in different languages? What if you introduce a 3rd client, written in a 3rd language (say C# on the server, Swift on iOS, and Java on Android)?
This is what Google uses Protobuf for [0]. A competing solution is JSONSchema, which gives a slightly different set of functionality than Protobuf.
You describe your interface once with JSONSchema, and compile it into interfaces/classes for your various clients/servers to consume. This gives you compile time safety, and eliminates the need to manually author these classes and manually keep them in sync between platforms.
As you scale up the number of services/clients/servers you're running, a system like this becomes not just helpful, but necessary to ensure that they can all talk to one another.
[0] https://developers.google.com/protocol-buffers/
We've gotten to a point where a human-readable, human-editable text format for structured data has become a complex nightmare where somebody can safely say "As many threads on xml-dev have shown, text-based processing of XML is hazardous at best" and be perfectly valid in saying it. -- Tom Bradford