```{post} 2021-01-20 --- tags: scrud, rest category: Introduction author: David Charboneau --- ``` [HTTP]: https://tools.ietf.org/html/rfc2616 "HTTP" [HTTP Link Header]: https://tools.ietf.org/html/rfc8288 "HTTP Link Header" [HTTP OPTIONS]: https://tools.ietf.org/html/rfc2616#section-9.2 "HTTP OPTIONS" [JSON-LD]: https://json-ld.org/ "JSON-LD" [JSON SCHEMA]: https://json-schema.org/ "JSON Schema" [OpenAPI]: http://spec.openapis.org/oas/v3.0.3 "OpenAPI" [REST]: https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm "REST API" [SCRUD]: https://gitlab.com/openteams/semantic-http-spec "SCRUD" # Introducing SCRUD ## TLDR; SCRUD is semantics for CRUD through REST. [SCRUD][SCRUD] is an approach to defining a [REST API][REST] that consistently provides discoverable schema and semantic meaning for your REST API resources. SCRUD stands for: Semantics for Create, Retrieve, Update, and Delete. Before we get into how SCRUD consistently provides discoverable schema and semantic meaning for REST APIs let's talk about why. ## Why SCRUD is motivated by observations about common approaches to REST API design. For example, [JSON Schema][JSON Schema] is great but it doesn't tell us what the data in a JSON resource mean. That's not entirely fair since documentation in your schema can tell a human what your data means, but text documentation in your schema it isn't usable by other software! You can't use documentation to drive automated UI choices, better indexing, etc.. Here are some additional observations: * Schema can give us tools for free, but those tools are limited to well-formedness due to a lack of associated meaning. * REST is great, but, it isn't descriptive enough when it comes to what is allowed. For example, if a URL supports POST of JSON resources, what is the schema of the POST content and what does the posted data mean? * [OpenAPI][OpenAPI] is great and helps solve some of the REST API documentation problem, but encourages a focus on URL patterns over hyptertextual resorces, making REST APIs unnecessarily difficult to consume. **Consuming a REST API should be driven by following the links through the application of HTTP verbs**. * OpenAPI tells the client about the entire API, but doesn't tell the client about any specific resource URL. This means that in order to discover what's supported by a given URL you have to consult the OpenAPI specification for the API - sorta like having to walk to a different table in a different room to use the tool that was right in front of you, and you have to know that the other table exists and where it's located. All of these observations can lead one to a conclusion: our REST APIs could be better documented, easier to consume, and software clients and libararies could do a lot more heavy lifting for developers and users if we improved the discoverability of the schema, semantics, and HTTP OPTIONS for all URLs. ## How All of the observations made so far have been made by others in a variety of settings. Those observations have led to a variety of solutions and standards that address one or two of the issues at at time. SCRUD chooses among the established standards and weaves them together with the goal of a cohesive whole. The existing standards SCRUD leverages include [HTTP][HTTP], [HTTP Link Header][HTTP Link Header], [JSON Schema][JSON Schema], [JSON-LD][JSON-LD], and an augmented [OpenAPI][OpenAPI] standard. SCRUD encourages defining JSON Schema and JSON-LD contexts for all request and response entities and providing them in response headers. SCRUD also defines an HTTP OPTIONS entity response format by borrowing from OpenAPI and encouraging the mention of JSON Schema and JSON-LD contexts ## What SCRUD is a [draft standard][SCRUD] defining basic expectations of a SCRUDful REST API. For a JSON REST API these expectations include: * A link header containing hyperlinks to a JSON Schema and JSON-LD context for all HTTP responses that include an entity body. * Support for OPTIONS for all URLs that provide response entities with OpenAPI HTTP Method content that provide links to the JSON Schema and JSON-LD Context for all entity request and response bodies. ### Examples #### HEAD ##### Request ```{sourcecode} http HEAD /api/partner-profiles/ HTTP/1.1 Host: openteams.com Accept: application/json ``` ##### Response ```{sourcecode} http HTTP/1.1 200 OK Content-Type: application/json Last-Modified: Wed, 20 Jan 2021 17:00:00 GMT ETag: "XXXXX" Link: ; rel="describedBy", ; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" ``` #### OPTIONS ##### Request ```{sourcecode} http OPTIONS /api/partner-profiles/ HTTP/1.1 Host: openteams.com Accept: application/json ``` ##### Response ```{sourcecode} http HTTP/1.1 200 OK Content-Type: application/json Last-Modified: Wed, 20 Jan 2021 17:00:00 GMT ETag: "XXXXX" Link: ; rel="describedBy", ; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" { "get": { "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": "http://api.openteams.com/collections-json-schema/partner-profiles", "context": "http://api.openteams.com/collections-json-ld/partner-profiles" } } } } }, "post": { "requestBody": { "description": "Create a new http://api.openteams.com/json-ld/partner-profiles resource.", "required": true, "content": { "schema": "http://api.openteams.com/json-schema/partner-profiles", "context": "http://api.openteams.com/json-ld/partner-profiles" } }, "responses": { "201": { "description": "CREATED. A new http://api.openteams.com/json-ld/partner-profiles resource was successfully created.", "headers": { "Location": "The URL of the created resource." } } } } } ``` This combination of always providing the link headers and providing an enriched version of HTTP OPTIONS support make the supported operations for an individual REST resource discoverable. What's more, it lays the foundation for a richly defaulted and extensible browsing client library. An early draft of the standard can be found [here](https://gitlab.com/openteams/semantic-http-spec). Our intent at OpenTeams is to submit an RFC to the IETF sometime later this year. OpenTeams has defined and begun adoption of SCRUD to better document our APIs and to enable our small team of developers to move faster by taking advantage of the information provided by SCRUD APIs. We have two primary SCRUD open source projects to date: scrud-django for implenting REST APIs and scrud-nuxt to support our front-end development. I'll be introducing these projects, soon! ## Summary SCRUD aims to add meaning and enriched discoverability to REST APIs to better support both the humans who write applications and for the tools that help them write applications. SCRUD accomplishes these goals by combining and adapting existing standards, including HTTP, HTTP Link Headers, JSON Schema, JSON-LD, and OpenAPI. At OpenTeams we've started two open source projects to build future OpenTeams capability on: scrud-django and scrud-nuxt.