ballerina-platform / ballerina-lang

The Ballerina Programming Language
https://ballerina.io/
Apache License 2.0
3.58k stars 737 forks source link

API call Invokes before API service get start up in the same package #3026

Closed randimaS closed 6 years ago

randimaS commented 7 years ago

This is the API service.

package News;

import ballerina.net.http;
import ballerina.lang.messages;

@http:configuration {basePath:"/cnn"}
service<http> CNNSportService {

    @http:GET {}
    @http:Path {value:"/sport"}
    resource cnnsportresource (message m) {

    json payload = {
                    "status": "ok",
                    "sources": [
                        {
                            "id": "bbc-sport",
                            "name": "BBC Sport",
                            "description": "The home of BBC Sport online. Includes live sports coverage, breaking news, results, video, audio and analysis on Football, F1, Cricket, Rugby Union, Rugby League, Golf, Tennis and all the main world sports, plus major events such as the Olympic Games.",
                            "url": "http://www.bbc.co.uk/sport",
                            "category": "sport",
                            "language": "en",
                            "country": "gb",
                            "urlsToLogos": {
                                "small": "",
                                "medium": "",
                                "large": ""
                            },
                            "sortBysAvailable": [
                                "top"
                            ]
                        }
                    ]
                };
        message response={};
        messages:setJsonPayload(response,payload);

        reply response;
    }
}

This is the client that invokes API call.

package News;

import ballerina.lang.system;
import ballerina.net.http;
import ballerina.lang.messages;

function main (string[] args) {
    getNews();

}

function getNews() (json) {

    message m = {};
    http:ClientConnector newsEP = create http:ClientConnector(
                                  "http://localhost:9090/cnn");

    message response = {};
    string requestPath  = "/sport";

    response = http:ClientConnector.get(newsEP,requestPath, m);

    json newsObject = messages:getJsonPayload(response);

    system:println(newsObject);
    return newsObject;
}

When this two files run as a package, API call invokes before the service is getting up. Is there a specific way to make wait the API calling function until API get hosted?.

VijithaEkanayake-zz commented 6 years ago

Hi @randimaS ,

Ballerina syntax has changed a bit when compared to the time you reported this issue. Earlier we had to start the service manually as we didn't have the VM level support to start the services automatically while running the package.

We already fixed this issue and you'll be able to execute the use case without any issues. I've written your ballerina code with latest syntax changes for your reference.

Here is the API service.

import ballerina/http;
import ballerina/log;

@http:ServiceConfig {
    basePath: "/cnn"
}
service<http:Service> CNNSportService bind { port: 9090 } {

    @http:ResourceConfig {
        methods: ["GET"],
        path: "/sport"
    }
    cnnsportresource(endpoint caller, http:Request request) {
        json payload = {
            "status": "ok",
            "sources": [
                {
                    "id": "bbc-sport",
                    "name": "BBC Sport",
                    "description":
                    "The home of BBC Sport online. Includes live sports coverage, breaking news, results,
                     video, audio and analysis on Football, F1, Cricket, Rugby Union, Rugby League, Golf, 
                     Tennis and all the main world sports, plus major events such as the Olympic Games."
                    ,
                    "url": "http://www.bbc.co.uk/sport",
                    "category": "sport",
                    "language": "en",
                    "country": "gb",
                    "urlsToLogos": {
                        "small": "",
                        "medium": "",
                        "large": ""
                    },
                    "sortBysAvailable": [
                        "top"
                    ]
                }
            ]
        };
        http:Response response = new;
        response.setPayload(payload);
        caller->respond(response) but {
            error e => log:printError("Error sending response", err = e)
        };
    }
}

This is the client that invokes API call.

import ballerina/http;
import ballerina/log;
import ballerina/io;

endpoint http:Client cnnEP {
    url: "http://localhost:9090/cnn"
};

function main (string... args) {
    json res = getNews();
    io:println(res);
}

function getNews() returns json {
    var backendRes = cnnEP->get("/sport");
    match backendRes {
        http:Response res => {
            json responseJson = check res.getJsonPayload();
            return responseJson;
        }
        error responseError => {
            json errorJson = {"message":"Error occurred while receiving the response"};
            return errorJson;
        }
    }
}

to execute sample as a package. first, init the package with ballerina init command. then run the package with ballerina run PACKAGE_NAME.

Here is the output :

screen shot 2018-05-21 at 10 37 57 am