2024 Jul 09 9:56 AM - edited 2024 Jul 09 9:08 PM
This is a task in the July Developer Challenge - "Reverse APIs".
This task is to add a second API endpoint to the service you already created in Task 1 - Your first service and first endpoint. It's nice and simple, and in fact is rather similar to the "Hello World!" example in Capire's "Getting Started" section ("Capire" is the friendly name for the CAP documentation). After you've completed this task, why don't you head over there and take a look around, as documentation goes, it's really rather awesome.
To complete this task successfully, all you have to do is implement another API endpoint and make it available in the service you created in the previous task, and of course submit it to be tested by the TESTER. That means adding that API endpoint definition to the service definition in your CDS model, and then writing the implementation for it.
Here are the specific requirements for this task.
The API endpoint should be made available within the existing service basic. Relative to the service path, the name should be hello and be requestable via an HTTP GET method.
It should have a single parameter, to, and should return a String value, in the context of a JSON payload that looks like this:
{ "@odata.context": "$metadata#Edm.String", "value": "Hello <value-of-argument-passed-to-the-to-parameter>!" }
🚨 Finally, be aware that the service should be served at the path /basic, and NOT at the path that's default for OData V4 services (which would be prefixed with /odata/v4). This was actually a requirement in the previous task - Task 1, but the TESTER was deliberately set to "lenient" mode for your very first API endpoint task. That "leniency mode" has been turned off now 🙂 So you may find yourself having to adjust your service so that it's served specifically at the /basic path. You may find the cds.serve() - @path section useful here.
When this API endpoint is added to the service and served via the OData V4 protocol, the service metadata document should look like this:
<?xml version="1.0" encoding="utf-8"?> <edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"> <edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/Common.xml"> <edmx:Include Alias="Common" Namespace="com.sap.vocabularies.Common.v1"/> </edmx:Reference> <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml"> <edmx:Include Alias="Core" Namespace="Org.OData.Core.V1"/> </edmx:Reference> <edmx:DataServices> <Schema Namespace="basic" xmlns="http://docs.oasis-open.org/odata/ns/edm"> <EntityContainer Name="EntityContainer"> <FunctionImport Name="ping" Function="basic.ping"/> <FunctionImport Name="hello" Function="basic.hello"/> </EntityContainer> <Function Name="ping" IsBound="false" IsComposable="false"> <ReturnType Type="Edm.String"/> </Function> <Function Name="hello" IsBound="false" IsComposable="false"> <Parameter Name="to" Type="Edm.String"/> <ReturnType Type="Edm.String"/> </Function> </Schema> </edmx:DataServices> </edmx:Edmx>
Once you've got your service defined, and a simple implementation ready with an on handler for the hello event, you're ready.
It is definitely worth testing it yourself first, e.g. with curl, Postman, or even the REST Client extension to VS Code that some of you are using (going on what I can see from some of your responses to the previous task). Use whatever tool you prefer for making HTTP calls.
With your server running (on, let's say, the default local CAP server port of 4004), make a request like this, supplying a value for the to parameter:
curl -s --url "localhost:4004/basic/hello(to='Zaphod')"
{"@odata.context":"$metadata#Edm.String","value":"Hello Zaphod!"}
Now you're ready to submit your CANDIDATE service, with the specific API endpoint, to the TESTER!
The task identifier you need to supply in the payload of your submission is: basic-hello.
You'll have already done this sort of thing in the previous task so just head back there for the more detailed instructions if you need them, or to the the section titled "The Tester service, and making a test request" in the main challenge blog post.
Now, to have your freshly minted API endpoint in this task tested, you'll need to submit a JSON payload like this:
{ "communityid": "<your-community-id>", "serviceurl": "<the-URL-of-your-service>", "task": "basic-hello" }
And, just as with the previous (and all further tasks):
the value for the communityid property should be your ID on this SAP Community platform (e.g. mine is "qmacro")
the value for the serviceurl property should be the absolute URL (i.e. including the scheme), of your CANDIDATE service which contains the API endpoint (see ℹ️ A note on URLs and services), not the full URL of the specific API endpoint itself
That's it!
Remember that you can check on your progress, and the progress of your fellow participants - all requests are logged and are available in an entity set served by the TESTER service. The entity set URL is https://developer-challenge-2024-07.cfapps.eu10.hana.ondemand.com/tester/Testlog and being an OData V4 entity set, all the normal OData system query options are available to you for digging into that information.
Until the next task, have fun, and if you have any questions or comments, leave them below!
2024 Jul 09 10:27 AM
Completed previous tasks as well. Pass!
2024 Jul 09 10:32 AM
2024 Jul 09 10:38 AM
2024 Jul 09 11:58 AM
@qmacro Sorry to be picky, given how helpful you were on Task 1 but the statement of requirement was
It should have a single parameter, to, and should return a String value, in the context of a JSON payload that looks like this:{ "@odata.context": "$metadata#Edm.String", "value": "Hello, <value-of-argument-passed-to-the-to-parameter>!" }
N.B. The comma. However the model answer says:
With your server running (on, let's say, the default local CAP server port of 4004), make a request like this, supplying a value for the to parameter:curl -s --url "localhost:4004/basic/hello(to='Zaphod')"
and the reponse should look like this:{"@odata.context":"$metadata#Edm.String","value":"Hello Zaphod!"}
N.B. No comma.
Either way:
2024 Jul 09 2:24 PM
Hey @geek ! Picky is good! And you gain extra kudos for being as sharp-eyed as this! You're right. Mea culpa, mea maxima culpa!
To those future readers (who will be reading this thread after I've fixed what @geek has pointed out), the problem was there was a comma in the first example of what was required ("Hello, <value-of-argument-passed-to-the-to-parameter>!") but not in the second example ("Hello Zaphod!").
2024 Jul 09 11:59 AM - edited 2024 Jul 09 12:09 PM
{"@odata.context":"$metadata#Edm.String","value":"PASS"}
@qmacro how are the TestLog results sorted?
Doesn't matter, this does what I want:
https://developer-challenge-2024-07.cfapps.eu10.hana.ondemand.com/tester/Testlog?$orderby=createdAt%...
2024 Jul 09 2:18 PM
Yep, you found the intent of my simple (lazy) design - use the 'managed' common aspect to enhance an otherwise very simple `Testlog` entity, to give us some sensible data (e.g. `createdAt`) that is auto-added, and eminently sortable and filterable.
2024 Jul 09 12:47 PM
2024 Jul 09 1:04 PM
Hello DJ @qmacro
{
ID: "4e51f802-24f1-438c-bc38-36a907d792b1",
task: "basic-hello",
result: "PASS",
createdAt: "2024-07-09T11:51:49.400Z",
createdBy: "Chanakya",
modifiedAt: "2024-07-09T11:51:49.400Z",
modifiedBy: "Chanakya",
serviceurl: "https://devchallenge-tasks.cfapps.us10-001.hana.ondemand.com/basic",
communityid: "cguttikonda24"
}
2024 Jul 09 1:56 PM
For those who want to use a Windows command line, here's what I successfully used:
curl ^
--data "{""communityid"":""mwn"",""serviceurl"":""https://mn.cfapps.us10-001.hana.ondemand.com/basic"",""task"":""basic-hello""}" ^
--header "Content-Type: application/json" ^
--url "https://developer-challenge-2024-07.cfapps.eu10.hana.ondemand.com/tester/testServer"
2024 Jul 09 2:15 PM
2024 Jul 09 3:25 PM
2024 Jul 09 5:34 PM - edited 2024 Jul 09 5:45 PM
Here's my submission:
Thanks to @MioYasutake for giving me the idea how to POST and GET to the tester service via http-file
2024 Jul 10 9:01 AM - edited 2024 Jul 10 9:02 AM
Awesome to see folks working with / learning from each other.
2024 Jul 09 7:14 PM
2024 Jul 09 7:50 PM
2024 Jul 09 9:00 PM
2024 Jul 09 9:48 PM
Finally got it working 🙂 It took me quite a while to realise that my test was failing because I missed the exclamation mark (!) in the result... "Hello Capirates!" 😄
2024 Jul 10 9:04 AM - edited 2024 Jul 10 9:05 AM
Nice test string, btw ("Capirates") 😉
BTW, I was meaning to ask you (as I noticed it in your response to a previous task) - do you use the `-k` curl option (to disable cert checks) deliberately? I'm curious, why do you do that (I'm thinking that I can learn something here, hence my question)?
2024 Jul 10 12:37 PM
Hi DJ,
Yes I used '-k' deliberately to bypass the certificate authentication issue (corporate laptop + docker container 😉 ) For some reasons I am getting certificate issues in my docker container, maybe I need to update the CA certificate my container. Hoping that fixes it!
2024 Jul 15 3:18 PM
2024 Jul 10 8:02 AM
2024 Jul 10 6:11 PM
2024 Jul 10 8:25 PM
2024 Jul 10 10:06 PM
Hello @qmacro ,
PFB the response from the Task 2 api endpoint -
And following is the response from the tester :
2024 Jul 11 8:19 AM
2024 Jul 12 1:26 AM
2024 Jul 12 9:23 AM
Hello,
please find the submission
Thanks,
Manoj Kumar Potharaju.
2024 Jul 14 1:38 PM
2024 Jul 21 10:47 AM
2024 Jul 23 5:27 AM
2024 Aug 01 9:28 AM
2024 Aug 01 8:43 PM