[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-10308":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":39,"readmeContent":40,"aiSummary":41,"trendingCount":16,"starSnapshotCount":16,"syncStatus":42,"lastSyncTime":43,"discoverSource":44},10308,"vulcain","dunglas\u002Fvulcain","dunglas","🔨 Fast and idiomatic client-driven REST APIs.","https:\u002F\u002Fvulcain.rocks",null,"Go",3579,103,50,20,0,6,58.65,"GNU Affero General Public License v3.0",false,"main",true,[24,25,26,27,28,29,30,31,32,33,34,35,36,37,5,38],"api","caddy","early-hints","graphql","hacktoberfest","http2","http2-push","http3","hypermedia-api","preload","rest","rest-api","reverse-proxy","server-push","vulcain-server","2026-06-12 04:00:49","\u003Ch1 align=\"center\">\u003Cimg src=\"vulcain.svg\" alt=\"Vulcain: Use HTTP\u002F2 Server Push to create fast and idiomatic client-driven REST APIs\" title=\"Use HTTP\u002F2 Server Push to create fast and idiomatic client-driven REST APIs\">\u003C\u002Fh1>\n\nVulcain is a brand new protocol using Preload hints and the `103 Early Hints` status code to create fast and idiomatic **client-driven REST** APIs.\n\nAn open source gateway server (a module for the [Caddy web server](https:\u002F\u002Fcaddyserver.com)), which you can put on top of **any existing web API** to instantly turn it into a Vulcain-compatible API is also provided!\n\nIt supports [hypermedia APIs](https:\u002F\u002Frestfulapi.net\u002Fhateoas\u002F) (e.g. any API created with [API Platform](https:\u002F\u002Fapi-platform.com)) but also any \"legacy\" API by documenting its relations [using OpenAPI](docs\u002Fgateway\u002Fopenapi.md).\n\n[![Plant Tree](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fdynamic\u002Fjson?color=brightgreen&label=Plant%20Tree&query=%24.total&url=https%3A%2F%2Fpublic.offset.earth%2Fusers%2Ftreeware%2Ftrees)](https:\u002F\u002Fplant.treeware.earth\u002Fdunglas\u002Fvulcain)\n[![PkgGoDev](https:\u002F\u002Fpkg.go.dev\u002Fbadge\u002Fgithub.com\u002Fdunglas\u002Fvulcain\u002Fgateway)](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fdunglas\u002Fvulcain)\n[![Build Status](https:\u002F\u002Fgithub.com\u002Fdunglas\u002Fvulcain\u002Fworkflows\u002FCI\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fdunglas\u002Fvulcain\u002Factions)\n[![codecov](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fdunglas\u002Fvulcain\u002Fbranch\u002Fmaster\u002Fgraph\u002Fbadge.svg)](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fdunglas\u002Fvulcain)\n[![Go Report Card](https:\u002F\u002Fgoreportcard.com\u002Fbadge\u002Fgithub.com\u002Fdunglas\u002Fvulcain)](https:\u002F\u002Fgoreportcard.com\u002Freport\u002Fgithub.com\u002Fdunglas\u002Fvulcain)\n\n[tabs]\n\n### Preload\n![Vulcain Schema](schemas\u002Fvulcain_doc_main_200.png)\n\n### Preload + Early Hints\n![Vulcain Schema](schemas\u002Fvulcain_doc_main_early_hints.png)\n\n### Server push\n![Vulcain Schema](schemas\u002Fvulcain_doc_main_server_push.png)\n\n[\u002Ftabs]\n\nGrab What You Need... Burn The REST!\n\n* [Introduction](#introduction)\n  * [Pushing Relations](#pushing-relations)\n  * [Filtering Resources](#filtering-resources)\n* [Gateway Server](docs\u002Fgateway\u002F)\n  * [Caddy Web Server Module](docs\u002Fgateway\u002Fcaddy.md)\n  * [Mapping a Non-Hypermedia API using OpenAPI](docs\u002Fgateway\u002Fopenapi.md)\n  * [Legacy Standalone Server](docs\u002Fgateway\u002Finstall.md)\n  * [Legacy Configuration](docs\u002Fgateway\u002Fconfig.md)\n* [Comparison with GraphQL and Other API Formats](docs\u002Fgraphql.md)\n* [Using GraphQL as Query Language for Vulcain](docs\u002Fgraphql.md#using-graphql-as-query-language-for-vulcain)\n* [Demo API](CONTRIBUTING.md)\n* [Cache Considerations](docs\u002Fcache.md)\n* [Formal Specification](spec\u002Fvulcain.md)\n* [Getting Help](docs\u002Fhelp.md)\n\nThe protocol has been published as [an Internet Draft](https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fdraft-dunglas-vulcain\u002F) that [is maintained in this repository](spec\u002Fvulcain.md).\n\nA reference, production-grade, implementation [**gateway server**](docs\u002Fgateway\u002Fcaddy.md) is also available in this repository.\nIt's free software (AGPL) written in Go. A Docker image is provided.\n\n## Introduction\n\nOver the years, several formats have been created to fix performance bottlenecks impacting web APIs: [over fetching, under fetching](https:\u002F\u002Fstackoverflow.com\u002Fa\u002F44568365\u002F1352334), [the n+1 problem](https:\u002F\u002Frestfulapi.net\u002Frest-api-n-1-problem\u002F)...\n\n[Current solutions for these problems (GraphQL, JSON:API's embedded resources and sparse fieldsets, ...)](docs\u002Fgraphql.md) are smart [network hacks](https:\u002F\u002Fapisyouwonthate.com\u002Fblog\u002Flets-stop-building-apis-around-a-network-hack) for HTTP\u002F1. But these hacks come with (too) many drawbacks when it comes to HTTP cache, logs and even security.\n\nFortunately, thanks to the new features introduced in HTTP\u002F2, it's now possible to create true REST APIs fixing these problems with ease and class! Here comes Vulcain!\n\nSee also [the comparison between Vulcain and GraphQL and other API formats](docs\u002Fgraphql.md).\n\n## Pushing Relations\n\n[tabs]\n\n### Preload\n![Preload Schema](schemas\u002Fvulcain_doc_preload_200.png)\n\n### Preload + Early Hints\n![Preload Schema](schemas\u002Fvulcain_doc_preload_early_hints.png)\n\n### Server push\n![Preload Schema](schemas\u002Fvulcain_doc_preload_server_push.png)\n\n[\u002Ftabs]\n\nConsidering the following resources:\n\n`\u002Fbooks`\n\n```json\n{\n    \"member\": [\n        \"\u002Fbooks\u002F1\",\n        \"\u002Fbooks\u002F2\"\n    ]\n}\n```\n\n`\u002Fbooks\u002F1`\n\n```json\n{\n    \"title\": \"1984\",\n    \"author\": \"\u002Fauthors\u002F1\"\n}\n```\n\n`\u002Fbooks\u002F2`\n\n```json\n{\n    \"title\": \"Homage to Catalonia\",\n    \"author\": \"\u002Fauthors\u002F1\"\n}\n```\n\n`\u002Fauthors\u002F1`\n\n```json\n{\n    \"givenName\": \"George\",\n    \"familyName\": \"Orwell\"\n}\n```\n\nThe `Preload` HTTP header introduced by Vulcain can be used to ask the server to immediately push resources related to the requested one using 103 Early Hints or HTTP\u002F2 Server Push:\n\n```http\nGET \u002Fbooks\u002F HTTP\u002F2\nPreload: \"\u002Fmember\u002F*\u002Fauthor\"\n```\n\nIn addition to `\u002Fbooks`, a Vulcain server will push the `\u002Fbooks\u002F1`, `\u002Fbooks\u002F2` and `\u002Fauthors\u002F1` resources!\n\nExample in JavaScript:\n\n```javascript\nconst bookResp = await fetch(\"\u002Fbooks\u002F1\", { headers: { Preload: `\"\u002Fauthor\"` } });\nconst bookJSON = await bookResp.json();\n\n\u002F\u002F Returns immediately, the resource has been pushed and is already in the push cache\nconst authorResp = await fetch(bookJSON.author);\n\u002F\u002F ...\n```\n\n[Full example, including collections](fixtures\u002Fstatic\u002Fmain.js), see also [use GraphQL as query language for Vulcain](docs\u002Fgraphql.md#using-graphql-as-query-language-for-vulcain).\n\nThanks to [HTTP\u002F2+ multiplexing](https:\u002F\u002Fstackoverflow.com\u002Fa\u002F36519379\u002F1352334), pushed responses will be sent in parallel.\n\nWhen the client will follow the links and issue a new HTTP request (for instance using `fetch()`), the corresponding response will already be in cache, and will be used instantly!\n\nFor non-hypermedia APIs (when the identifier of the related resource is a simple string or int), [use an OpenAPI specification to configure links between resources](docs\u002Fgateway\u002Fopenapi.md).\nTip: the easiest way to create a hypermedia API is to use [the API Platform framework](https:\u002F\u002Fapi-platform.com) (by the same author as Vulcain).\n\nWhen possible, we recommend using [Early Hints](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc8297) (the 103 HTTP status code) to push the relations.\nVulcain allows to gracefully fallback to [`preload` links](https:\u002F\u002Fwww.w3.org\u002FTR\u002Fpreload\u002F) in the headers of the final response or to [HTTP\u002F2 Server Push](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc7540#section-10.1) when the 103 status code isn't supported.\n\n### Query Parameter\n\nAlternatively to HTTP headers, the `preload` query parameter can be used:\n\n[tabs]\n\n#### Preload\n![Preload Query Schema](schemas\u002Fvulcain_doc_preload_query_200.png)\n\n#### Preload + Early Hints\n![Preload Query Schema](schemas\u002Fvulcain_doc_preload_query_early_hints.png)\n\n#### Server push\n![Preload Query Schema](schemas\u002Fvulcain_doc_preload_query_server_push.png)\n\n[\u002Ftabs]\n\n## Filtering Resources\n\n[tabs]\n\n### Preload\n![Filter Schema](schemas\u002Fvulcain_doc_filter_200.png)\n\n### Preload + Early Hints\n![Filter Schema](schemas\u002Fvulcain_doc_filter_early_hints.png)\n\n### Server push\n![Filter Schema](schemas\u002Fvulcain_doc_filter_server_push.png)\n\n[\u002Ftabs]\n\nThe `Fields` HTTP header allows the client to ask the server to return only the specified fields of the requested resource, and of the preloaded related resources.\n\nMultiple `Fields` HTTP headers can be passed. All fields matching at least one of these headers will be returned. Other fields of the resource  will be omitted.\n\nConsidering the following resources:\n\n`\u002Fbooks\u002F1`\n\n```json\n{\n    \"title\": \"1984\",\n    \"genre\": \"novel\",\n    \"author\": \"\u002Fauthors\u002F1\"\n}\n```\n\n`\u002Fauthors\u002F1`\n\n```json\n{\n    \"givenName\": \"George\",\n    \"familyName\": \"Orwell\"\n}\n```\n\nAnd the following HTTP request:\n\n```http\nGET \u002Fbooks\u002F1 HTTP\u002F2\nPreload: \"\u002Fauthor\"\nFields: \"\u002Fauthor\u002FfamilyName\", \"\u002Fgenre\"\n```\n\nA Vulcain server will return a response containing the following JSON document:\n\n```json\n{\n    \"genre\": \"novel\",\n    \"author\": \"\u002Fauthors\u002F1\"\n}\n```\n\nIt will also push the following filtered `\u002Fauthors\u002F1` resource:\n\n```json\n{\n    \"familyName\": \"Orwell\"\n}\n```\n\n### Query Parameter\n\nAlternatively to HTTP headers, the `fields` query parameter can be used to filter resources:\n\n[tabs]\n\n#### Preload\n![Fields Schema](schemas\u002Fvulcain_doc_filter_query_200.png)\n\n#### Preload + early hints\n![Fields Schema](schemas\u002Fvulcain_doc_filter_query_early_hints.png)\n\n#### Server push\n![Fields Schema](schemas\u002Fvulcain_doc_filter_query_server_push.png)\n\n[\u002Ftabs]\n\n## See Also\n\n* [Mapping a non-hypermedia API using OpenAPI](docs\u002Fgateway\u002Fopenapi.md)\n* [Cache considerations](docs\u002Fcache.md)\n* [Using GraphQL with Vulcain](docs\u002Fgraphql.md#using-graphql-as-query-language-for-vulcain)\n* [Using other selectors such as XPath and CSS selectors for non-JSON documents](spec\u002Fvulcain.md#selectors) (only JSON Pointer [is currently supported](https:\u002F\u002Fgithub.com\u002Fdunglas\u002Fvulcain\u002Fissues\u002F3) by the Gateway Server)\n\n## License and Copyright \n\ntl;dr:\n\n* proprietary software **can** implement the Vulcain specification\n* proprietary software **can** be used behind the Vulcain Gateway Server without having to share their sources\n* modifications made to the Vulcain Gateway Server **must** be shared\n* alternatively, a commercial license is available for the Vulcain Gateway Server\n\n[The specification](spec\u002Fvulcain.md) is available under [the IETF copyright policy](https:\u002F\u002Ftrustee.ietf.org\u002Fcopyright-faq.html). The Vulcain **specification** can be implemented by any software, including proprietary software.\n\nThe Vulcain Gateway Server is licensed under [AGPL-3.0](LICENSE). This license implies that if you modify the Vulcain Gateway Server, you must share those modifications. However, the AGPL-3.0 license applies only to the gateway server itself, **not to software used behind the gateway**.\n\nFor companies not wanting, or not able to use AGPL-3.0 licensed software, commercial licenses are also available. [Contact us for more information](mailto:kevin+vulcain@dunglas.dev).\n\n## Treeware\n\nThis package is [Treeware](https:\u002F\u002Ftreeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https:\u002F\u002Fplant.treeware.earth\u002Fdunglas\u002Fvulcain) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.\n\n## Credits\n\nCreated by [Kévin Dunglas](https:\u002F\u002Fdunglas.dev). Sponsored by [Les-Tilleuls.coop](https:\u002F\u002Fles-tilleuls.coop).\n\nSome ideas and code used in Vulcain's reference implementation have been taken from [Hades](https:\u002F\u002Fgithub.com\u002Fgabesullice\u002Fhades) by [Gabe Sullice](https:\u002F\u002Fgithub.com\u002Fgabesullice), an HTTP\u002F2 reverse proxy for JSON:API backend.\n\nSee also [the prior arts](docs\u002Fprior-art.md).\n","Vulcain 是一个用于创建快速且符合语义的客户端驱动REST API的新协议。它利用HTTP\u002F2 Server Push和`103 Early Hints`状态码来优化API性能，同时支持超媒体API（如使用API Platform构建的API）及通过OpenAPI文档化的传统API。该项目提供了一个开源网关服务器模块，可以与Caddy Web服务器集成，将任何现有的Web API转换为Vulcain兼容格式。此工具特别适合需要提高数据加载速度、减少延迟的应用场景，例如移动应用后台服务或对响应时间有高要求的企业级系统。",2,"2026-06-11 03:27:43","top_topic"]