Skip to content

Commit

Permalink
More docs updates
Browse files Browse the repository at this point in the history
  • Loading branch information
darrelmiller committed Feb 28, 2021
1 parent 7f00e40 commit 39eeffd
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 205 deletions.
10 changes: 2 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
# Project

> This repo has been populated by an initial template to help get you started. Please
> make sure to update the content to build a great experience for community-building.
Kiota is project to build an OpenAPI based code generator for creating SDKs for HTTP APIs. The goal is to produce a lightweight, low maintenance, code generator that is fast enough to run as part of the compile time tool-chain but scalable enough to handle the largest APIs. Kiota generates a lightweight set of strongly typed classes that layer over a core HTTP library and product an intuitive and discoverable way of creating HTTP requests. A set of abstractions decouple the generated service library from the core allowing a variety of core libraries to be supported.

As the maintainer of this project, please make a few updates:

- Improving this README.MD file to provide a great experience
- Updating SUPPORT.MD with content about this project's support experience
- Understanding the security reporting process in SECURITY.MD
- Remove this section from the README
This library builds on top of the [Microsoft.OpenAPI.NET](https://github.com/microsoft/openapi.net) library to ensure comprehensive support for APIs that use OpenAPI descriptions. One of the goals of the project is to provide the best code generator support possible for OpenAPI and JSON Schema features.

## Contributing

Expand Down
16 changes: 2 additions & 14 deletions SUPPORT.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
# TODO: The maintainer of this repo has not yet edited this file

**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?

- **No CSS support:** Fill out this template with information about how to file issues and get help.
- **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport).
- **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide.

*Then remove this first heading from this SUPPORT.MD file before publishing your repo.*

# Support

## How to file issues and get help
Expand All @@ -16,10 +6,8 @@ This project uses GitHub Issues to track bugs and feature requests. Please searc
issues before filing new issues to avoid duplicates. For new issues, file your bug or
feature request as a new Issue.

For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
For help and questions about using this project, please uses the GitHub discussions.

## Microsoft Support Policy

Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
Support for this **PROJECT** is limited to the resources listed above.
59 changes: 46 additions & 13 deletions docs/kiotaabstractions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,61 @@ On most platforms there are a range of different HTTP client library implementat
The HTTP core interface is the primary point where Kiota service libraries will trigger the creation of a HTTP request.

```csharp
public interface IHttpCore<TNativeResponse>
{
Task<Stream> SendAsync(RequestInfo requestInfo);
Task<TNativeResponse> SendNativeAsync(RequestInfo requestInfo);
public interface IHttpCore {
Task<ModelType> SendAsync<ModelType>(RequestInfo requestInfo, IResponseHandler responseHandler = default);
}
```

Kiota service libraries support two ways to access the response of an HTTP call. The first is the simplest and assumes that the core library will process the HTTP status codes and only return a stream of the response body. The service library will process this stream and deserialize into the appropriate model object. If an error is detected in core, an exception will be thrown up to be caught by the calling application. This is the classic RPC model.

The second method returns a "native response object" that allows the caller direct access to the HTTP response. This type of method is provided to deal with scenarios where standard RPC behavior is not appropriate for handling the response. The type of the native response object is defined by the core library and is the same type for all request builders. This type is provided to the code generator to ensure the native methods are generated correctly.
Kiota service libraries return the model type that is associated with HTTP resource. This behavior can be overriden by changing the `responseHandler` to do something different than default behavior. One use of this is to change the response type to be either a native HTTP response class, or return a generic API response class that provides access to more underlying metadata.

## RequestInfo

In order to enable Kiota service libraries to make requests, they need to be able accumulate information about the request and pass it to the core library. The RequestInfo object is designed to do that. It only contains properties that be provided by the request builders. As request builders get more sophisticated, so may the RequestInfo class.

```csharp
public class RequestInfo
{
public string Path;
public string HttpMethod;
public IDictionary<string, object> QueryParameters = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
public IDictionary<string, string> Headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
public Stream Content;
{
public Uri URI { get; set; }
public HttpMethod HttpMethod { get; set; }
public IDictionary<string, object> QueryParameters { get; set; } = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
public IDictionary<string, string> Headers { get; set; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
public Stream Content { get; set; }
}
```

```TypeScript
export interface RequestInfo {
URI?: URL;
httpMethod?: HttpMethod;
content?: ReadableStream;
queryParameters?: Map<string, object>;
headers?: Map<string, string>;
}
```

```java
public class RequestInfo {
@Nullable
public URI uri;
@Nullable
public HttpMethod httpMethod;
@Nonnull
public HashMap<String, Object> queryParameters = new HashMap<>(); //TODO case insensitive
@Nonnull
public HashMap<String, String> headers = new HashMap<>(); // TODO case insensitive
@Nullable
public InputStream Content;
}
```

## ResponseHandler

TBD
- This allows core to do all the default hard work, but enables a custom response handler to change the behavior of the method.

```CSharp
public interface IResponseHandler
{
Task<ModelType> HandleResponseAsync<NativeResponseType, ModelType>(NativeResponseType response);
}
```
173 changes: 3 additions & 170 deletions docs/requestbuilders.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,175 +11,8 @@ By creating properties on request builder classes, the developer can effectively

```csharp

namespace Todo {


public class TodoClient {
private RequestInfo requestInfo = new RequestInfo();
private IHttpCode httpCore;

public TodoClient(IHttpCore httpCore, string basePath) {
requestInfo.AddPath(path);
}

public TodosRequestBuilder Todos {

get {
return new TodosRequestBuilder(this.httpCore, requestInfo.Path + "todos");
}
}
}

public class TodosRequestBuilder {
private RequestInfo requestInfo = new RequestInfo();
private IHttpCode httpCore;

public TodosRequestBuilder(IHttpCore httpCore, string basePath) {
requestInfo.AddPath(path);
}

public TodoIdRequestBuilder this[string TodoId] {
get {
return new TodoIdRequestBuilder(this.httpCore, Path + "/" + TodoId);
}
}
}

public class TodoIdRequestBuilder {
private RequestInfo requestInfo = new RequestInfo();
private IHttpCode httpCore;

}
}

var todo = todoClient.Todos["<todoId>"].GetAsync();
var responsiblePerson = todoClient.Todos["<todoId>"].AssignedTo.GetAsync();
```
Each request builder class exposes the set of HTTP methods that are supported on that resource.

```csharp

namespace Todo {

var client = new TodoClient();

public class TodoClient: TodoClient<GraphResponse> {

}

public class TodoClient<T>
{
private RequestInfo requestInfo = new RequestInfo();
private IHttpCore httpCore;

public TodoClient(IHttpCore httpCore, string path)
{
requestInfo.AddPath(path);
this.httpCore = httpCore;
}


public TodosRequestBuilder Todos
{
get
{
return new TodosRequestBuilder(this.httpCore, requestInfo.Path + "todos");
}
}
}

public class TodosRequestBuilder<NativeResponse>
{
private RequestInfo requestInfo = new RequestInfo();
private IHttpCore httpCore;

public TodosRequestBuilder(IHttpCore httpCore, string path)
{
this.httpCore = httpCore;
this.requestInfo.AddPath(path);
}
public static Task<IEnumerable<Todo>> DefaultResponseHandlerAsync(Stream content) { return null; }
public Func<Stream, Task<IEnumerable<Todo>>> ResponseHandler { get; set; } = DefaultResponseHandlerAsync;
public Func<Todo, Stream> CreateContent { get; set; }

public TodoIdRequestBuilder this[string TodoId]
{
get
{
return new TodoIdRequestBuilder(this.httpCore, requestInfo.Path + "/" + TodoId);
}
}

public async Task<NativeResponse> GetNativeResponseAsycn() {

}

public async Task<IEnumerable<Todo>> GetAsync(Action<GetQueryParameters> q = default(Action<GetQueryParameters>))
{
return await ResponseHandler(await this.httpCore.SendAsync(this.requestInfo.With(RequestMethod.get).WithParameters(q)));
}

public async Task<NativeResponse> GetNativeAsync(Action<GetQueryParameters> q = default(Action<GetQueryParameters>))
{
return await this.httpCore.SendNativeAsync(this.requestInfo.With(RequestMethod.get).WithParameters(q));
}

public async Task<IEnumerable<Todo>> PostAsync(Todo todo)
{
RequestInfo request = this.requestInfo.With(RequestMethod.post).WithContent(this.CreateContent(todo));
return await ResponseHandler(await this.httpCore.SendAsync(request));
}

public class GetQueryParameters : QueryParameters
{
public bool active
{
get { return Get<bool>("active"); }
set { Set("active", value); }
}
public string keyword
{
get { return Get<string>("keyword"); }
set { Set("keyword", value); }
}
}
}

public class TodoIdRequestBuilder
{
private readonly RequestInfo requestInfo = new RequestInfo();
private readonly IHttpCore httpCore;

public TodoIdRequestBuilder(IHttpCore httpCore, string path)
{
this.httpCore = httpCore;
this.requestInfo.AddPath(path);
}

public static Todo DefaultResponseHandlerAsync(Stream content) { return null; }
public Func<Stream, Todo> ResponseHandler { get; set; } = DefaultResponseHandlerAsync;

public async Task<Todo> GetAsync(Action<GetQueryParameters> q = default(Action<GetQueryParameters>))
{
return ResponseHandler(await this.httpCore.SendAsync(this.requestInfo.With(RequestMethod.get)));
}
public async Task<Todo> DeleteAsync(Action<DeleteQueryParameters> q = default(Action<DeleteQueryParameters>))
{
return ResponseHandler(await this.httpCore.SendAsync(this.requestInfo.With(RequestMethod.delete)));
}

public class GetQueryParameters
{
}
public class DeleteQueryParameters
{
}
}
}

```

Once the desired resource is selected, the developer can then select the required HTTP method and execute the call.

```csharp
var client = new TodoClient(new HttpClient());
var todo = client.Todos[123].GetAsync();
```
Each request builder class exposes the set of HTTP methods that are supported on that resource. Each operation method allows setting configuring query parameters, setting HTTP headers and providing a custom response handler.
10 changes: 10 additions & 0 deletions tests/kiota.core.integrationtests/ToDoApi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ paths:
responses:
'200':
description: OK
content:
application/json:
schema:
title: collectionTodos
type: object
properties:
value:
items:
$ref: "#/components/schemas/todo"

post:
responses:
'201':
Expand Down

0 comments on commit 39eeffd

Please sign in to comment.