@hexarc/pact-tool

Node.js CLI tool to generate API clients from Hexarc Pact protocols for TypeScript.


Keywords
http, pact, protocol, schema, client, codegen, typescript, api, aspnet, discovery, dotnet, integration, json, webapi
License
MIT
Install
npm install @hexarc/pact-tool@2.0.0

Documentation

Hexarc Pact

Hexarc Pact provides a toolchain for exposing and consuming Web API for .NET/TypeScript-based projects.

Develop your .NET Web API project with Pact to keep a single source of truth for the API metadata and consume it across the .NET ecosystem (microservices, desktop and mobile applications) or on the Web via TypeScript.

Package Platform Version Downloads
Hexarch.Pact.Protocol .NET 7.0+ Version Downloads
Hexarch.Pact.AspNetCore .NET 7.0+ Version Downloads
Hexarch.Pact.Client .NET 7.0+ Version Downloads
Hexarch.Pact.Tool .NET 7.0+ Version Downloads
@hexarc/pact-tool TypeScript Version Downloads

What's in Pact?

Features

  • Hassle-free API integrations in seconds.
  • No type information loosing. Consume exact API as it's designed.
  • Code first. No need to describe your API protocol in external IDL/DSL.
  • Charged with advanced types. Not only simple DTOs but enums, generics, tagged unions, etc.

Type system

The Pact type system is based on the .NET CLR types with some bespoke ones for the best development experience.

What's inside the Pact type system:

  • Primitive types (including Guid and DateTime)
  • Value/Reference type semantics
  • Collections and generics (not only simple arrays and dictionaries)
  • Complete support for Nullable Reference Type annotations (NRT)
  • Enums (string-based and number-based)
  • Tagged Unions (via Hexarc.Serialization.Union)
  • Tuples (via Hexarc.Serialization.Tuple)

API annotation rules

The Pact API schema is designed to have an RPC-like semantic. In doing so an exposed API must follow these rules:

  • API controllers must be marked with standard ApiController and Route attributes.
  • Route attribute must have only a constant string path without templating (e.g. [Route("Entities")]).
  • API methods must be marked with one of the supported HTTP verbs (HttpGet or HttpPost). Verb attributes may contain an endpoint path. Others are not supported at the moment.
    • HttpGet methods can have query parameters which must be bind via the FromQuery attribute.
    • HttpPost methods must have only one parameter which is the request body.
  • API method path can be specified in the HTTP verb attribute or the Route attribute. If the method path is not specified in the HTTP verb attribute it will be taken from the Route one or an exception will be raised.

Additional attributes

Pact provides some useful attributes for API annotation:

  • PactIgnoreAttribute can be applied to API controllers or methods to be excluded from an API schema.
  • PactScopeAttribute can be applied to API controllers to be isolated into specific scope in an API schema.

Demo API server

Demo API server can be found at https://hexarc-demo-api.herokuapp.com/.

The Pact API schema is exposed at https://hexarc-demo-api.herokuapp.com/pact/schema.

To generate an API client use the instruction below.

How to use

Find out how to use Pact to expose and consume a typical Web API.

Expose Pact API schema

  1. Install the Hexarc.Pact.AspNetCore package in a .NET Web API project:
dotnet add package Hexarc.Pact.AspNetCore
  1. Add the Pact schema generation in the Startup.ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    // Register the Pact schema generation.
    services.AddPactGeneration();
}
  1. Enable the Pact middleware in the Startup.Configure method:
public void Configure(IApplicationBuilder app)
{
    // Enable the Pact middleware to expose the generated API schema.
    app.UsePact();

    app.UseRouting();
    app.UseEndpoints(endpoints => endpoints.MapControllers());
}
  1. Implement an API controller according to the Pact annotation rules:
[ApiController, Route("Misc")]
public sealed class MiscController : ControllerBase
{
    [HttpGet(nameof(Ping))]
    public String Ping([FromQuery] String message) => $"Hello, {message}";
}
  1. Start the app and open the YOUR_API_HOST/pact/schema address to ensure the Pact API schema is generated.

Consume Pact API schema

  1. Install the Hexarc.Pact.Client package in a .NET project:
dotnet add package Hexarc.Pact.Client
  1. Install the Hexarc.Pact.Tool tool in the project:
dotnet tool install Hexarc.Pact.Tool

You may need to setup a .NET tools manifesto before install the Hexarc.Pact.Tool tool:

dotnet new tool-manifest
  1. Add a pact.json config in the project with a desired API client generation settings:
{
   "schemaUri": "YOUR_API_HOST/pact/schema",
   "clientClassName": "DemoClient",
   "clientClassNamespace": "DemoNamespace",
   "outputDirectory": "Generated"
}

where

  • schemaUri - link to a Pact API schema
  • clientClassName - name for a generated API client class
  • clientClassNamespace - namespace where to put in the generated API client class
  • outputDirectory - output directory for the generated sources
  1. Generate the API client via the Pact CLI tool:
dotnet pact

This command must be performed in the same folder with the pact.json config.

  1. The generated API client will be available for accessing the API server:
var client = new DemoClient(new HttpClient { BaseAddress = new Uri("YOUR_API_HOST") });
var pong = await client.Misc.Ping("World");
Console.WriteLine(pong); // Prints "Hello, World" to the output.

Acknowledgments

Built with JetBrains tools for Open Source projects.

JetBrains Logo (Main) logo

License

MIT © Max Koverdyaev