Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator
HTTP requests have never been so easy
https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator
Last synced: about 1 month ago
JSON representation
HTTP requests have never been so easy
- Host: GitHub
- URL: https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator
- Owner: pedro-gilmora
- Created: 2022-10-17T12:33:55.000Z (about 2 years ago)
- Default Branch: dev
- Last Pushed: 2024-03-19T16:57:08.000Z (9 months ago)
- Last Synced: 2024-08-06T10:01:12.840Z (4 months ago)
- Language: C#
- Size: 241 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: ReadMe.md
Awesome Lists containing this project
- RSCG_Examples - SourceCrafter.HttpServiceClientGenerator - gilmora/SourceCrafter.HttpServiceClientGenerator/ (Contributors Welcome for those / 1. [ThisAssembly](https://ignatandrei.github.io/RSCG_Examples/v2/docs/ThisAssembly) , in the [EnhancementProject](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementproject) category)
README
# 🍰 **SourceCrafter.HttpClientGenerator**: Web API source generator for API interfaces.
## You just can build | update | generate* your API calls
### Under these premises
- Properties and indexers will generate path segments, encoded to url components
- Methods are HTTP verbs invokers for GET, DELETE, POST, PUT and PATCH requests (e.g.: `GetAsync(...)`), with the following parameters _(all of them are optional):_
- **`TResponse?`**: Return type for the async method
- **`TContent? content`**: For POST, PUT and PATCH requests content.
- **`TQuery? query`**: Generic parameter to be serialized into URL query components
- **`Action? requestHandler`**: A handler for requests before send it to the server
> Usage: Set some information to headers, transform
- **`Action? requestHandler`**: A handler for after get the response and before serialize the possible content coming from the server
> Usage: Collect information from response headers, evaluate response composition
- **`CancellationToken? cancelToken`**: A cancellation token for this task### Operation metadata (comments before)
| Key | Description |
|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`queryParamName`** | Sets the query parameter name. Defaults to query. E.g.: `?status=pending` whereas status is the `queryParamName` for a value type parameter |
| **`contentParamName`** | Sets the content parameter name. Defaults to content. For `MultipartFormData` or `FormUrlEncoded` content types creates a named item for value type parameters |
| **`contentFormatType`** | Determines the content format type. `MultipartFormData` and `FormUrlEncoded`. For `Xml`, a `StreamContent` is created to transport the serialized data. `Json` uses the same `System.Net.Http.Json.JsonContent` are available |
| **`responseFormatType`** | Determines the response format type. Just `Xml` and `Json` |> Rest of `{key}: {value}` pairs parsed on comments will be trated as request headers
---
### The client
```csharp
// Generates a client class with the following name convention
// Takes Name from I{Name}Api and adds 'Client' to the end
var _petStoreClient = new PetStoreClient();
```### The usage
```csharp
//will produce a call to https://petstore.swagger.io/v2/store/inventory
var inventory = await _petStoreClient.Store.Inventory.GetAsync();
```### The structure (*generated)
```csharp
[HttpOptions(
//API Url
"https://petstore.swagger.io/v2/",
// Url Encode properties are formatted specific casing (CamelCase, PascalCase, Upper and Lower snake casing)
QueryCasing = Casing.CamelCase,
// Path segments casing format
PathCasing = Casing.CamelCase,
// Enum values casing format on query and path. None for its underlying value
EnumQueryCasing = Casing.CamelCase,
// Enum values casing format on content serialization
EnumSerializationCasing = Casing.CamelCase,
// Properties casing format on content serialization
PropertyCasing = Casing.CamelCase
)]
public interface IPetStoreApi
{
IStore Store { get; }
IPet Pet { get; }
IUser User { get; }
}public interface IStore
{
IOrder Order { get; }
IStoreInventory Inventory { get; }
}public interface IPet
{
IPetActionsByPetId this[long petId] { get; }
IPetActionsByStatus FindByStatus { get; }
IOrderActions Order { get; }
}public interface IOrder:
IPost
{
IOrderActionsByOrderId this[int orderId] { get; }
}public interface IOrderActionsByOrderId :
IGet,
IDelete
{
}public interface IPetActionsByStatus :
// queryParamName: status
IGet>
{
}
public interface IOrderActions:
IPost,
IPut
{
}public interface IPetActionsByPetId :
IGet,
IDelete,
IPost
{
IPetActionsByPetIdUploadImage UploadImage { get; }
}
public interface IPetActionsByPetIdUploadImage :
// contentParamName: file
IPost
{
}public interface IStoreInventory: IGet>
{
}public interface IUser:IPost
{
IUserActionsByUserName this[string userName] { get; }
}public interface IUserActionsByUserName :
IGet,
IDelete,
IPut
{}
```### The models
```csharp
public enum PetStatus
{
Available, Pending, Sold
}public enum OrderStatus
{
Placed, Approved, Delivered
}public class Order
{
public int Id { get; set; }
public int PetId { get; set; }
public int Quantity { get; set; }
public DateTime ShipDate { get; set; }
public OrderStatus Status { get; set; }
public bool Complete { get; set; }
}public class ApiResponse
{
public int Code { get; set; }
public string Type { get; set; }
public string Message { get; set; }
}public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}public class Pet
{
public long Id { get; set; }
public Category Category { get; set; }
public string Name { get; set; }
public string[] PhotoUrls { get; set; }
public Tag[] Tags { get; set; }
public PetStatus Status { get; set; }
}public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
}public class User
{
public long Id { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string Phone { get; set; }
public int UserStatus { get; set; }
public OrderStatus Status { get; set; }
}
```---
### Generated contentThe following interface
```csharp
public interface IPetActionsByPetIdUploadImage :
// contentParamName: file
IPost
{
}
```would generate the following service class (based on the previous definition example):
```csharp
//
using static SourceCrafter.HttpServiceClient.GeneratorHelpers;
using System.Net.Http.Json;
using System.IO;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
using Domain.Service.Models;
using SourceCrafter.HttpServiceClient;namespace Domain.Service
{
public class PetActionsByPetIdUploadImageService : IPetActionsByPetIdUploadImage
{
private readonly PetStoreAgent _agent;
private readonly string _path;
internal PetActionsByPetIdUploadImageService(PetStoreAgent agent, string path)
{
_agent = agent;
_path = path;
}public async Task PostAsync(FileInfo file, Func beforeSend = default, Func afterSend = default, CancellationToken cancellationToken = default)
{
var request = new HttpRequestMessage(HttpMethod.Post, new Uri(_path, UriKind.Relative)) {
Content = GeneratorHelpers.CreateMultipartFormData(ArrayFrom((file.ToByteArrayContent(), "file", file.Name)))
};
var response = await _agent._httpClient.SendAsync(request, cancellationToken);return response switch
{
{ IsSuccessStatusCode: true, Content: {} responseContent } =>
await responseContent.ReadFromJsonAsync(_agent._jsonOptions, cancellationToken),{ IsSuccessStatusCode: false } =>
throw new HttpRequestException(response.ReasonPhrase),_ => default(ApiResponse)
};
}
}
}
```