Functional

Live on this server

Uses delegates to implement a web service, similar to ASP.NET Core Minimal APIs.

The book shelf API of the webservice sample, written as delegates instead of a class - similar to the Minimal APIs of ASP.NET Core. Inline.Create() takes one delegate per HTTP method (and path, such as :id for the id of a book); GenHTTP reads their parameters from the request and writes their result as the response.

This keeps small APIs short. The books live in a local list here, which the delegates share.

To run it, create a console app (dotnet new console), add GenHTTP (dotnet add package GenHTTP.Full), replace Program.cs with the code below and start it with dotnet run - it answers at http://localhost:8080/.

Program.cs46 lines
using GenHTTP.Engine.Internal;

using GenHTTP.Api.Content;
using GenHTTP.Api.Protocol;

using GenHTTP.Modules.Functional;
using GenHTTP.Modules.Layouting;
using GenHTTP.Modules.Practices;

var books = new List<Book> { new(1, "Lord of the Rings") };

var bookApi = Inline.Create()
                    .Get(() => // GET /books/
                    {
                        lock (books) return books.ToList();
                    })
                    .Put((Book book) => // PUT /books/ with a book as JSON, XML, ...
                    {
                        lock (books)
                        {
                            if (books.Count >= 50)
                            {
                                throw new ProviderException(ResponseStatus.Conflict, "The shelf is full, please delete a book first");
                            }

                            var added = book with { Id = books.Select(b => b.Id).DefaultIfEmpty().Max() + 1 };

                            books.Add(added);

                            return added;
                        }
                    })
                    .Delete(":id", (int id) => // DELETE /books/1
                    {
                        lock (books) return books.RemoveAll(b => b.Id == id);
                    });

var app = Layout.Create()
                .Add("books", bookApi);

await Host.Create()
          .Handler(app)
          .Defaults()
          .RunAsync();

public record Book(int Id, string Title);

Try it

Send the requests to the sample running on this server - change the path, headers or body as you like, or copy them as curl commands.

  1. List all books

    GET
    curl -i 'https://genhttp.org/demo/functional/books/'
  2. Add a book

    PUT
    Headers and body
    curl -i -X PUT -H 'Content-Type: application/json' -d '{ "title": "The Hobbit" }' 'https://genhttp.org/demo/functional/books/'
  3. Delete a book

    DELETE
    Headers and body
    curl -i -X DELETE 'https://genhttp.org/demo/functional/books/1'