GithubHelp home page GithubHelp logo

Comments (9)

max-ieremenko avatar max-ieremenko commented on June 16, 2024

Hi igalHcsra,

Thank you for request. I put your topic in my todo list.

What I can see right away is a possible limitation to only unary methods and POST. In any case requires some research.

from servicemodel.grpc.

max-ieremenko avatar max-ieremenko commented on June 16, 2024

Hi igalHcsra,

I have no plans to integrate ServiceModel.Grpc with Microsoft.AspNetCore.Grpc.HttpApi: HttpApi is in alpha state.

I like the idea about swagger support, there for ServiceModel.Grpc.AspNetCore.Swashbuckle is released in version 1.2.0.
Integration is in a pre-release state.
Please check this example SwashbuckleSwaggerIntegration.

Your feedback is appreciated.

from servicemodel.grpc.

igalHcsra avatar igalHcsra commented on June 16, 2024

Hi Max,
Works great!
Thank you very much for everything, I see you really put the effort in that one.
Can I somehow get the swagger request "Try it out" method to work with JsonElement?
JsonElement is a crucial feature in swagger for dynamic objects to be serialized, in the current swagger implementation it is not being serialized.

from servicemodel.grpc.

max-ieremenko avatar max-ieremenko commented on June 16, 2024

Hi igalHcsra,

i have doubts that i understand your question about JsonElement. Do you ask about contract like this?

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    Task<JsonElement> Ping(JsonElement element1, JsonElement element2);
}

from servicemodel.grpc.

igalHcsra avatar igalHcsra commented on June 16, 2024
[DataContract]
public class TestContract
{
    [DataMember]
    public JsonElement TestDynamicData { get; set; }
}

from servicemodel.grpc.

max-ieremenko avatar max-ieremenko commented on June 16, 2024

Behind the scenes http request from swagger UI is converted into standard gRPC request by ServiceModel.Grpc HTTP/1.1 JSON gateway.
Before "Try it out" from swagger UI, please make sure that standard gRPC communication is working.

I assume you already have the following service implementation:

[DataContract]
public class TestContract
{
    [DataMember]
    public JsonElement TestDynamicData { get; set; }
}

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    Task<TestContract> Ping(TestContract contract);
}

public class Startup
{
	public void ConfigureServices(IServiceCollection services)
	{
		services.AddServiceModelGrpc(options => 
		{
			// here should be marshaller factory, which can correctly serialize and deserialize instance of TestContract
			options.DefaultMarshallerFactory = new ...
		});
	}
}

Test gRPC client call, example can be found here

var clientFactory = new ClientFactory
{
	// here should be marshaller factory, which can correctly serialize and deserialize instance of TestContract, the same as in Startup.cs on server 
	MarshallerFactory = new ...
};

var channel = new Channel("localhost", 5000, ...);
var proxy = clientFactory.CreateClient<ITestService>(channel);

var contract = new TestContract
{
	TestDynamicData = ... // set JsonElement
};
await proxy.Ping(contract);

when proxy.Ping(contract) works then you can use swagger UI "Try it out" with following JSON:

{
	"contract": {
		"testDynamicData": {
			"property1": 1,
			"property2": "some text"
		}
	}
}

JsonElement in the TestContract can be correctly handled by System.Text.Json.JsonSerializer.
ServiceModel.Grpc does not provide MarshallerFactory based on System.Text.Json.JsonSerializer.

The following implementation can be used:

public sealed class JsonMarshallerFactory : IMarshallerFactory
{
	public Marshaller<T> CreateMarshaller<T>()
	{
		return new Marshaller<T>(Serialize, Deserialize<T>);
	}

	private static void Serialize<T>(T value, SerializationContext context)
	{
		using (var buffer = context.AsStream())
		using (var writer = new Utf8JsonWriter(buffer))
		{
			JsonSerializer.Serialize(writer, value);
		}

		context.Complete();
	}

	private static T Deserialize<T>(DeserializationContext context)
	{
		var reader = new Utf8JsonReader(context.PayloadAsReadOnlySequence());
		return JsonSerializer.Deserialize<T>(ref reader)!;
	}
}

from servicemodel.grpc.

igalHcsra avatar igalHcsra commented on June 16, 2024

The marshaller works great it really covers the swagger functionallity to the fullest, is there a way to use the marshaller for sending also 'object' or 'dynamic' types as well?
I think I'll make the serializer to differ when it comes from the swagger client or any other so when it's a swagger call it will use the jsonMarshaller and when it comes from c# client then use an 'object' type.

from servicemodel.grpc.

max-ieremenko avatar max-ieremenko commented on June 16, 2024

is there a way to use the marshaller for sending also 'object' or 'dynamic' types as well?

As you can see it is fully under your control.

Swagger call is just an emulation of client call

Standard gRPC workflow for client call:

  1. client call
  2. marshaller.serialize() request
  3. http call
  4. marshaller.deserialize() request
  5. invoke you service
  6. marshaller.serialize() response
  7. http response
  8. marshaller.deserialize() response

Swagger UI call:

  1. http request with json body
  2. ServiceModel.Grpc HTTP/1.1 JSON gateway deserialize from json
  3. ServiceModel.Grpc HTTP/1.1 JSON gateway make gRPC request
  4. marshaller.serialize() request
  5. invoke gRPC (the same as for client call)
  6. marshaller.deserialize() request (the same as for client call)
  7. invoke you service (the same as for client call)
  8. marshaller.serialize() response (the same as for client call)
  9. ServiceModel.Grpc HTTP/1.1 JSON gateway marshaller.deserialize() response
  10. ServiceModel.Grpc HTTP/1.1 JSON gateway serialize response into json
  11. return json to Swagger UI

from servicemodel.grpc.

igalHcsra avatar igalHcsra commented on June 16, 2024

Brilliant! Thank you very much Max you are exellent!

from servicemodel.grpc.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.