{"id":37050466,"url":"https://github.com/depfac/dfakto.rest","last_synced_at":"2026-01-14T05:50:59.591Z","repository":{"id":34922279,"uuid":"191444302","full_name":"depfac/dFakto.rest","owner":"depfac","description":"Small component to help implement best REST API design guidelines in dotnet core","archived":false,"fork":false,"pushed_at":"2024-07-09T21:36:28.000Z","size":149,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-12-29T20:32:49.448Z","etag":null,"topics":["core","dotnet","hal","hateoas","rest-api"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/depfac.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-11T20:26:41.000Z","updated_at":"2023-05-02T02:54:28.000Z","dependencies_parsed_at":"2023-01-15T10:26:09.403Z","dependency_job_id":null,"html_url":"https://github.com/depfac/dFakto.rest","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/depfac/dFakto.rest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depfac%2FdFakto.rest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depfac%2FdFakto.rest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depfac%2FdFakto.rest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depfac%2FdFakto.rest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/depfac","download_url":"https://codeload.github.com/depfac/dFakto.rest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depfac%2FdFakto.rest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28411660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["core","dotnet","hal","hateoas","rest-api"],"created_at":"2026-01-14T05:50:58.966Z","updated_at":"2026-01-14T05:50:59.582Z","avatar_url":"https://github.com/depfac.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dFakto.Rest\n\nAccording to Roy Fielding, [you may call your API a REST API only if you make use of hypertext](https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)\n\nThe dFakto.Rest project contains components to ease the creation of REST API following the best practices described in the \n[Hypertext Application Language](https://en.wikipedia.org/wiki/Hypertext_Application_Language) specification and in books like [\"Rest In Practice\"](https://www.amazon.com/gp/product/0596805829?ie=UTF8\u0026tag=martinfowlerc-20\u0026linkCode=as2\u0026camp=1789\u0026creative=9325\u0026creativeASIN=0596805829) \nand [\"REST API Design Cookbook\"](https://www.amazon.com/REST-Design-Rulebook-Mark-Masse/dp/1449310508/).\n\nThe project is composed of 3 components\n* dFakto.Rest.Abstractions project contains base classes and interfaces\n* dFakto.Rest.System.text.Json an implementation based on System.Text.Json\n* dFakto.Rest.AspNetCore.Mvc contains component to ease integration of dFakto.Rest into ASPNET Core projects.\n\n## Quick example to create a Resource :\n\n```c#\n\nusing dFakto.Rest;\nusing dFakto.Rest.System.text.Json;\n\nvar factory = new ResourceFactory(options);\n\nvar author = factory.Create(new Uri(\"http://example.com/api/authors/12345\"))\n     .Add(new\n     {\n         Name = \"Marcel Proust\",\n         BirthDate = new DateTime(1871, 7, 10)\n     });\n\nvar result = factory.Create(new Uri(\"http://example.com/api/books/in-search-of-lost-time\"))\n     .Add(new {Title = \"In Search of Lost Time\"})\n     .AddEmbedded(\"author\",author);\n\nvar resourceJsonSerializer = _factory.CreateSerializer();\nvar json = await resourceJsonSerializer.Serialize(result);\n```\nWill return the following Json\n```json\n{\n   \"_links\": {\n     \"self\": {\n       \"href\": \"http://example.com/api/book/in-search-of-lost-time\"\n     }\n   },\n   \"_embedded\": {\n      \"author\": {\n         \"_links\": {\n           \"self\": {\n             \"href\": \"http://example.com/api/users/12345\"\n           }\n         },\n         \"name\" : \"Marcel Proust\",\n         \"birthdate\": \"1871-07-10T00:00:00.00\"\n      }\n   },\n   \"title\": \"In Search of Lost Time\"\n}\n```\n\n## How to integrate into ASP.NET Core project\n\n\n### First add the reference to your project\n```\nInstall-Package dFakto.Rest.Asbtractions\nInstall-Package dFakto.Rest.System.Text.Json\nInstall-Package dFakto.Rest.AspNetCore.Mvc\n```\n\n### Update your Startup.cs file\n\n```c#\npublic void ConfigureServices(IServiceCollection services)\n{\n ...\n    services.AddRest(new JsonSerializerOptions()\n    {\n        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\n        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault\n    });\n    \n    // Register Formatter to use application/hal+json MediaType\n    services.AddControllers(x =\u003e\n    {\n        x.InputFormatters.Add(new ResourceInputFormatter());\n        x.OutputFormatters.Add(new ResourceOutputFormatter());\n    });\n...\n}\n```\n\n#### Example of Controller\n\n```c#\nclass  MyController : Controller\n{\n    private IResourceFactory _factory;\n    \n    // Inject Resource Factory \n    public MyController(IResourceFactory resourceFactory){\n        _factory = resourceFactory;\n    }\n    \n    [HttpGet(\"/{id}\",Name = \"getbyid\")]\n    public ActionResult\u003cIResource\u003e Get(int id, [FromQuery] ResourceRequest request)\n    {\n        var domainEntity = GetDomainEntity();\n        \n        var result = _resourceFactory.Create(Url.LinkUri(\"getbyid\", new {id = sampleValue.Id}))\n            .AddLink(\"somelink\", new Link(Url.LinkUri(\"getallvalues\")))\n            .Add(sampleValue);\n         \n        return Ok(result);\n    }\n}\n```\nFor more information, look at the sample project\n\n## Expand Middleware (Hypertext Cache Pattern)\nA special middleware can be integrated to load linked resource as embedded automatically based on the \"expand\" parameter\n\nTo enable this middleware, you have to update your Startup.cs file\n\n### Register and configure the Middleware in Dependency Injection\n```c#\npublic void ConfigureServices(IServiceCollection services)\n{\n ...\n    services.AddExpandMiddleware(o =\u003e o.RequestTimeout = 10);\n ...\n}\n```\n### Insert the Middleware\n```c#\npublic void Configure(IApplicationBuilder app, IHostingEnvironment env)\n{\n...\n    app.UseExpandMiddleware(); // Register Expand Middleware before UseMvc() call.\n    \n    app.UseEndpoints(endpoints =\u003e {\n        endpoints.MapControllers();\n    });\n...\n}\n\n```\n\nOnce the Middleware integrated, you can pass the name of the link you want to retrieve\nas embedded resource using the expand query string parameter\n\nExample: \n\n```json\nGET http://myapi/resource\n\n{\n   \"_links\": {\n     \"self\": {\"href\": \"http://myapi/resource\"},\n     \"other\": {\"href\":  \"http://myapi/other/2323\"}\n   },\n   \"field1\": \"1\"\n}\n```\nAdding the \"expand\" query string parameter and specify the link we want to expand\n```json\nGET http://myapi/resource?expand=other\n\n{\n   \"_links\": {\n     \"self\": {\"href\": \"http://myapi/resource\"},\n     \"other\": {\"href\":  \"http://myapi/other/2323\"}\n   },\n   \"_embedded\": {\n      \"other\": {\n        \"_links\": {\n           \"self\": {\"href\": \"http://myapi/other/2323\"}\n         },\n         \"field1\":4,\n         \"field2\":10,\n         \"field3\":\"hello\",\n      }\n  },\n  \"field1\": \"1\"\n}\n```\nThe returned resource will contains the embedded without changing anything in the Controller.\n\nIt is possible to specify the name of an embedded resource link by using the format \"embedded.link\" as value for the expand parameter.\n\nAs the middleware retrieve the resources using HTTP GET calls, it may be more efficient to let the controller\nretrieve the resource if it can be retrieve locally (in the same controller or in another Controller). If the controller process the \"expand\" parameter\nand add the embedded resource, the middleware will not process it again.\n\n## Delimited values parameters\nASP.NET Core MVC does not support delimited values for query string parameters because it is not standard.\n\nFor example, the uri http://someuri/api?param=val1,val2,val3 cannot be mapped as a string[] in your request object.\n(To do so, you have to repeat the attribute name \"?param=val1\u0026param=val2...\")\n\nTo support the delimited values parameters, you can register the following ProviderFactory\n\n```c#\nservices.AddMvc(options =\u003e options.ValueProviderFactories.AddDelimitedValueProviderFactory(','))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdepfac%2Fdfakto.rest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdepfac%2Fdfakto.rest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdepfac%2Fdfakto.rest/lists"}