there is a web service (WCF Service Library) when I debug the web service project (in Visual Studio) "Test Client WCF" is launched (so I guess its hosted via the Test Client). I have a web service method called "Test" which returns string. When I "call" that method with the Test Client WCF - it works.
When I want to use browser as a client. I go to http://localhost:9001/Name/WebService/WebAPI and I see the web service (xml with some info about methods). And now I want to use JavaScript to call that Test method.
I created a client similar to this https://stackoverflow.com/a/11404133 and I replace the sr variable (SOAP request) with a request, which is in XML part of the Test method in the "Test Client WCF" and for url I chose http://localhost:9001/Name/WebService/WebAPI . I tried that JavaScript client, but I got some client error -
content-type 'text-xml' is invalid, server wanted
'application/soap+xml; charset=utf-8'
(unfortunately right now I can't get to the web service, so I don’t know a number of the error and exact message, but there was no other information, beside the content-type). So I changed the request header to 'application/soap+xml; charset=utf-8', but then I got error – that tells me:
The message cannot be processed at the receiver, due to an
AddressFilter mismatch at the EndpointDispatcher. Check that the
sender and receiver's EndpointAddresses agree
(Or something like that - I had to translated it to english)
I also tried the "JavaScript client" with an existing service, that I found on the internet and with text/xml content-type. And it works fine.
Please do you have any advice - how to call the Test method with JavaScript? Thanks.
The service invocated in Javascript is called Restful style service. WCF is able to create a Restful style service too. But we need to set up some kinds of additional configuration. The service is hosting in IIS express when we test the service in Visual Studio. It uses the default binding configuration to host the service(BasicHttpBinding), called SOAP web service. The universal way to invocate the service is taking advantage of using service proxy class, that is what the WCFTestClient do.
If we want to invocate the service by using JavaScript, here is a simple demo, wish it is useful to you. Please be aware that the project template is WCF Service Application instead of Service Library project.
https://stackoverflow.com/questions/56873239/how-to-fix-err-aborted-400-bad-request-error-with-jquery-call-to-c-sharp-wcf/56879896#56879896
Feel free to let me know if there is something I can help with.
I searched all over the web looking for the C# .NET classes and documentation to allow me to code functional equivalent of this Python method and I can't believe it simply doesn't exist but NuGet hasn't helped and the closest Google documentation I can find is here.
What does exist is classes and examples that show how to authenticate a .NET server or Installable with Google so that it can Access various APIs (Drive etc) but I just want the simple client token Authentication that is referred to for most other languages here
As you will see Python has the google.oauth2.id_token class with its verify_oauth2_token() method and NodeJS and PHP have their verifyIdToken() methods.
Java gets a little more complicated with: -
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
// Specify the CLIENT_ID of the app that accesses the backend:
.setAudience(Collections.singletonList(CLIENT_ID))
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
// (Receive idTokenString by HTTPS POST)
GoogleIdToken idToken = verifier.verify(idTokenString);
But C# has diddly :-( Please advise!
If it helps I'm implementing a Javascript SSO client. (BTW have no interest in the YOLO library)
I finally found Google C# token verification code on the web. It says it is no longer actively maintained. Why is there no MuGet package? Why is Google making this so hard?
Or just call the Google Validator like Python does?
Also see previous answer Here
Introduction
I have a SAP HANA Cloud Platform account. I have also deployed a Java application to the account and created a test servlet, which returns dummy data.
On the other side i have a SAP UI5 application which i develop on the WebIDE. I created also two destinations:
Destination "virtualTEST" is connected to a SAP Backend System (HANA Cloud Connector)
Destination "javaTEST" is connected to my Java servlet application
The neo-app.json is well configured and can obtain data from the test servlet (the dummy data) and data from the SAP Backend System (OData Gateway).
The problem
Now i want to pass variables to the SAP Backend System (virtualTEST) destination, which should not be visible in the frontend to avoid javascript manipulation.
My first thought
My first thought was that i create a new servlet which acts as proxy. In the SAPUI5 i call the servlet from javaTEST destination and pass the "hidden variables" like /testServlet?targetUrl=https://webide-xxx.hana.ondemand.com/sap/opu/odata/TEST_SRV/TEST?$filter=Var eq '{{MYVAR}}' and the Java application replaces {{MYVAR}} with my real variable. Then the target will be loaded (this is also a destination url to my SAPUI5 application). This does not work, i do not know why, but i think the proxy can not obtain data from the destination of an application.
Also, i think this is not the best solution. How can this be solved? Any ideas or best practices? Can destinations be used in Java application? :)
It is not really clear to me what you want to achieve. Of cause you can call destinations from Java.
<resource-ref>
<res-ref-name>myBackend</res-ref-name>
<res-type>com.sap.core.connectivity.api.http.HttpDestination</res-type>
</resource-ref>
import javax.naming.Context;
import javax.naming.InitialContext;
import com.sap.core.connectivity.api.http.HttpDestination;
...
// coding to lookup the destination "myBackend"
Context ctx = new InitialContext();
HttpDestination destination = (HttpDestination)
ctx.lookup("java:comp/env/myBackend");
// coding to call service "myService" on the system configured in the given destination
HttpClient createHttpClient = destination.createHttpClient();
HttpGet get = new HttpGet("myService");
HttpResponse resp = createHttpClient.execute(get);
from the official documentation. in the HttpGet you could set Params if you like.
In my opion your Backend should be so save you don't have to worry about Javascript manipulations, especially not for exposed OData services
Regards
Mathias
We want to build a Javascript/HTML gui for our gRPC-microservices. Since gRPC is not supported on the browser side, we thought of using web-sockets to connect to a node.js server, which calls the target service via grpc.
We struggle to find an elegant solution to do this. Especially, since we use gRPC streams to push events between our micro-services.
It seems that we need a second RPC system, just to communicate between the front end and the node.js server. This seems to be a lot of overhead and additional code that must be maintained.
Does anyone have experience doing something like this or has an idea how this could be solved?
Edit: Since Oct 23,2018 the gRPC-Web project is GA, which might be the most official/standardized way to solve your problem. (Even if it's already 2018 now... ;) )
From the GA-Blog: "gRPC-Web, just like gRPC, lets you define the service “contract” between client (web) and backend gRPC services using Protocol Buffers. The client can then be auto generated. [...]"
We recently built gRPC-Web (https://github.com/improbable-eng/grpc-web) - a browser client and server wrapper that follows the proposed gRPC-Web protocol. The example in that repo should provide a good starting point.
It requires either a standalone proxy or a wrapper for your gRPC server if you're using Golang. The proxy/wrapper modifies the response to package the trailers in the response body so that they can be read by the browser.
Disclosure: I'm a maintainer of the project.
Unfortunately, there isn't any good answer for you yet.
Supporting streaming RPCs from the browser fully requires HTTP2 trailers to be supported by the browsers, and at the time of the writing of this answer, they aren't.
See this issue for the discussion on the topic.
Otherwise, yes, you'd require a full translation system between WebSockets and gRPC. Maybe getting inspiration from grpc-gateway could be the start of such a project, but that's still a very long shot.
An official grpc-web (beta) implementation was released on 3/23/2018. You can find it at
https://github.com/grpc/grpc-web
The following instructions are taken from the README:
Define your gRPC service:
service EchoService {
rpc Echo(EchoRequest) returns (EchoResponse);
rpc ServerStreamingEcho(ServerStreamingEchoRequest)
returns (stream ServerStreamingEchoResponse);
}
Build the server in whatever language you want.
Create your JS client to make calls from the browser:
var echoService = new proto.grpc.gateway.testing.EchoServiceClient(
'http://localhost:8080');
Make a unary RPC call
var unaryRequest = new proto.grpc.gateway.testing.EchoRequest();
unaryRequest.setMessage(msg);
echoService.echo(unaryRequest, {},
function(err, response) {
console.log(response.getMessage());
});
Streams from the server to the browser are supported:
var stream = echoService.serverStreamingEcho(streamRequest, {});
stream.on('data', function(response) {
console.log(response.getMessage());
});
Bidirectional streams are NOT supported:
This is a work in progress and on the grpc-web roadmap. While there is an example protobuf showing bidi streaming, this comment make it clear that this example doesn't actually work yet.
Hopefully this will change soon. :)
https://github.com/tmc/grpc-websocket-proxy sounds like it may meet your needs. This translates json over web sockets to grpc (layer on top of grpc-gateway).
The grpc people at https://github.com/grpc/ are currently building a js implementation.
The repro is at https://github.com/grpc/grpc-web (gives 404 ->) which is currently (2016-12-20) in early access so you need to request access.
GRPC Bus WebSocket Proxy does exactly this by proxying all GRPC calls over a WebSocket connection to give you something that looks very similar to the Node GRPC API in the browser. Unlike GRPC-Gateway, it works with both streaming requests and streaming responses, as well as non-streaming calls.
There is both a server and client component.
The GRPC Bus WebSocket Proxy server can be run with Docker by doing docker run gabrielgrant/grpc-bus-websocket-proxy
On the browser side, you'll need to install the GRPC Bus WebSocket Proxy client with npm install grpc-bus-websocket-client
and then create a new GBC object with: new GBC(<grpc-bus-websocket-proxy address>, <protofile-url>, <service map>)
For example:
var GBC = require("grpc-bus-websocket-client");
new GBC("ws://localhost:8080/", 'helloworld.proto', {helloworld: {Greeter: 'localhost:50051'}})
.connect()
.then(function(gbc) {
gbc.services.helloworld.Greeter.sayHello({name: 'Gabriel'}, function(err, res){
console.log(res);
}); // --> Hello Gabriel
});
The client library expects to be able to download the .proto file with an AJAX request. The service-map provides the URLs of the different services defined in your proto file as seen by the proxy server.
For more details, see the GRPC Bus WebSocket Proxy client README
I see a lot of answers didn't point to a bidirectional solution over WebSocket, as the OP asked for browser support.
You may use JSON-RPC instead of gRPC, to get a bidirectional RPC over WebSocket, which supports a lot more, including WebRTC (browser to browser).
I guess it could be modified to support gRPC if you really need this type of serialization.
However, for browser tab to browser tab, request objects are not serializsed and are transfered natively, and the same with NodeJS cluster or thread workers, which offers a lot more performance.
Also, you can transfer "pointers" to SharedArrayBuffer, instead of serializing through the gRPC format.
JSON serialization and deserialization in V8 is also unbeatable.
https://github.com/bigstepinc/jsonrpc-bidirectional
Looking at the current solutions with gRPC over web, here is what's available out there at the time of writing this (and what I found):
gRPC-web: requires TypeScript for client
gRPC-web-proxy: requires Go
gRPC-gateway: requires .proto modification and decorations
gRPC-bus-websocket-proxy-server: as of writing this document it lacks tests and seems abandoned (edit: look at the comments by the original author!)
gRPC-dynamic-gateway: a bit of an overkill for simple gRPC services and authentication is awkward
gRPC-bus: requires something for the transport
I also want to shamelessly plug my own solution which I wrote for my company and it's being used in production to proxy requests to a gRPC service that only includes unary and server streaming calls:
gRPC-express
Every inch of the code is covered by tests. It's an Express middleware so it needs no additional modifications to your gRPC setup. You can also delegate HTTP authentication to Express (e.g with Passport).
I have an application on Google App Engine written in python, i am using this application as a server to my web application written in PHP which i am using as client to call my server side api on GAE using javascript end point.
I want to upload file from my web application to my GAE application using google cloud end points.I studied about blob store but it didn't help much.
Please suggest what should i do.
You have to use the Cloud Storage to store your files, instead of Blobstore.
Use GCS because:
Google is moving away from the blobstore
GCS offers more functionality like acl, folders, and more.
You can use filenames and a blobstore like serving url for images
You can create serving url's for non images
GCS is cheap and has a free default bucket
To using GCS, you have to use the https://cloud.google.com/appengine/docs/python/googlecloudstorageclient/
Here is an exemple in Java to use this API:
GcsService gcsService = GcsServiceFactory.createGcsService();
GcsFilename filename = new GcsFilename(CONSTANTES.BUCKETNAME, unique+".jpg");
GcsFileOptions options = new GcsFileOptions.Builder()
.mimeType("image/jpg")
.acl("public-read")
.build();
GcsOutputChannel writeChannel = gcsService.createOrReplace(filename, options);
EDIT: This is written (my mistake) as if you were on java. Feel free to use the analogous pattern for PHP on App Engine.
What the other user wrote about GCS answers the storage portion of your question - you should definitely use GCS - but as far as your idea of POSTing the form data to an endpoints function, this is definitely not advised. API calls should be little tiny pieces of data. An API should be like a paper airplane, lightly flying to your server to request some real data.
The way to have users upload files to GCS is to serve them a page with a file upload form (enctype="multipart/form-data") where the form action parameter is an upload URL generated to template the page in your servlet's doGet(HttpServletRequest req, HttpServletResponse resp) method using the GCS client library function createUploadUrl(). You can use it like this:
String uploadUrl = blobstoreService
.createUploadUrl("/upload",
UploadOptions.Builder.withGoogleStorageBucketName("my_bucket"));
In this manner you can obtain an upload URL for GCS that the user's file POST will go to. The route /upload is a route on your app that will be redirected once the upload is received. Any extra form parameters you add will still be visible to the request handler (a doPost() method on a servlet) which you define for that route.
With all of this info, you're ready to begin serving file upload forms to your users, without worrying about how this interacts with Cloud Endpoints. Use Endpoints to define API calls needed by your javascript/Android/iOS client, not for handling file uploads.