Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

SAP Developer Challenge - APIs - Task 1 - List the Northwind entity sets

qmacro
Developer Advocate
Developer Advocate
34,294

(Check out the SAP Developer Challenge - APIs blog post for everything you need to know about the challenge to which this task relates!)

In this task you'll become acquainted with entity sets in the classic Northwind service.

Background

You may have heard of, or even interacted with an instance of, the Northwind model and service, originally and properly called "Northwind Traders". It has a classic and well-known set of related entities and is often a first introduction for many to database schemas, OData services and more. It was originally shipped with the Microsoft Access database application.

The entities and their relationships are easy to understand and it's partly for this reason that it's so popular. In this task, you will briefly explore the Northwind service offered by OASIS Open, the non-profit standards body, where there's a working group that looks after the Open Data Protocol (OData) standard.

There are various services available at the simple landing page at https://services.odata.org and the one we will use is the OData V4 version, which is available directly at this address:

https://services.odata.org/V4/Northwind/Northwind.svc/

Your task

Your task specifically is to list the entity sets available in this service. They should be presented as a single string, following these rules:

  • the entity set names should be exactly as specified in the service
  • you should keep whatever case the entity set names are written in
  • the entity sets should be listed in alphabetical order
  • they should be comma-separated, with no spaces

Here's a short example of what a list should look like:

Categories,Customers,Suppliers

There are more entity sets than just these three, this is just an example.

Once you have constructed the list, you should hash it and post the hash as a new reply to this discussion thread, as described in Task 0 - Learn to share your task results. This means that to get the hash, you would need to make a call to the hash service like this (based again on the above short example), supplying your SAP Community ID in the appropriate header too:

https://developer-challenge.cfapps.eu10.hana.ondemand.com/v1/hash(value='Categories,Customers,Suppliers')

Hints and tips

What is an entity set? It is essentially a collection (a set) of entities. There are two places where an OData service typically details the entity sets on offer. One is the service document, available at the root of the service's base URL. And the other is the metadata document, available at the service's base URL with $metadata appended. Metadata documents contain a wealth of information for an OData service; the entity set details are included, but there's a lot of other information that is included too, information that you must exclude or otherwise ignore. Simpler perhaps would be to take the service document, which has a set of collections (this harks back to the origins of OData, incidentally) which more or less equate to entity sets.

If you request the service document (https://services.odata.org/V4/Northwind/Northwind.svc/) in your browser, you get an XML based representation in response. You can parse this XML with any XML library, or command line tool (such as xmlstarlet or xmllint.

While the service document's XML structure is much simpler than the metadata document, it's still XML, and it's arguably easier these days to avoid XML altogether when doing ad-hoc parsing activities. With OData V2 services, the service document is only available in an XML representation. It's also available in a JSON representation with OData V4 services.

Using a command line HTTP client, for example, to request the service document, we get an entirely different representation.

For example, this invocation of curl:

curl \
  --url "https://services.odata.org/V4/Northwind/Northwind.svc/"

returns a JSON representation, that looks like this (redacted for brevity):

{
  "@odata.context": "https://services.odata.org/V4/Northwind/Northwind.svc/$metadata",
  "value": [
    {
      "name": "Categories",
      "kind": "EntitySet",
      "url": "Categories"
    },
    {
      "name": "CustomerDemographics",
      "kind": "EntitySet",
      "url": "CustomerDemographics"
    },
    {
      "name": "Customers",
      "kind": "EntitySet",
      "url": "Customers"
    },
    {
      "name": "Employees",
      "kind": "EntitySet",
      "url": "Employees"
    },
    {
      "name": "Order_Details",
      "kind": "EntitySet",
      "url": "Order_Details"
    }
  ]
}

In case you're interested, the shell pipeline to produce this redacted representation was:

curl \
  --silent \
  --url "https://services.odata.org/V4/Northwind/Northwind.svc/" \
  | jq '.value|=.[:5]'

Once you have a JSON representation of the service document, you can use your favorite language (JavaScript, TypeScript, Python, ABAP, or perhaps jq) to parse out the entity set names, and form them, in alphabetical order, into the comma-separated list that you need.

Of course, if you prefer to parse the XML representation of the service document, then by all means do that.

For discussion

We get different representations of the service document resource, depending on where we make the request. In the browser, the representation comes back in XML form. Using curl on the command line, the representation is in JSON form. Why do you think that is?

226 REPLIES 226

ajmaradiaga
Developer Advocate
Developer Advocate
13,225

615e85240b2b40ad34999c0286eaccf6e2342ba9f97c16728430cea20773f3dc

qmacro
Developer Advocate
Developer Advocate
13,216

That's what I call keen! Good work 🙂

ajmaradiaga
Developer Advocate
Developer Advocate
13,184

My RSS reader "notified" me of today's task 😉

tobiasz_h
Active Participant
0 Kudos
13,123

e9fd0523db9f34a66a2dbeb9ebc64b55a5ed17c344e6c0f3c47be2507e9c9a2e

VenugopalA
Explorer
0 Kudos
13,092

c73f7c84c08796a400964d2641b24120e538eab527a97537be87070362600544

SandipAgarwalla
Active Contributor
0 Kudos
13,090

0f01d357e485fd5c43f4faca9c214c023546cc245fc982fee0c5d4480fd59210

cguttikonda24
Participant
0 Kudos
13,107

741ca07242e615cc3d9d351ad5872d806250c8b4ab1135bf604cd18079a91e48

0 Kudos
13,083

you might want to check again through the precise instructions in Task 0 regarding posting a reply with your hash, @cguttikonda24 🙂

0 Kudos
13,043

Hello DJ @qmacro 

What did I missing in generating the hash as per the Task-0.

Used the same endpoint with the value of all entities in alphabetical order and passed the community id as a header.

 

 

12,995

Your CommunityId is public (cguttikonda24), you don't have to obscure it, but the entities you should 😉

0 Kudos
12,987

Hahah...True. Its an overkill.  😀

12,879

Yes @cguttikonda24 please obscure the string of entity sets in your screenshot!

12,899

Compare your reply to replies from others in this thread 😉

0 Kudos
12,829

Got it...😮

UweFetzer_se38
Active Contributor
0 Kudos
13,105

206a0baa95d89bac061c1564cda3152e8b742ab0c4fc67aac7a72b1c179e854c

Eurey
Discoverer
0 Kudos
13,091

6cf3d2621ee5f4efb2aaf06d7a20eed1f3902ff2886843c7d5ec5c7a5cb4467c

emiliocampo
Explorer
0 Kudos
13,083

2cbbe85945eade4a51d16ec7c4e5bae88ccc244a260baa9d66f572fc79182263

qmacro
Developer Advocate
Developer Advocate
0 Kudos
13,081

For those that have posted hashes already ( @ajmaradiaga @tobiasz_h  @VenugopalA @SandipAgarwalla @UweFetzer_se38 @Eurey @emiliocampo ) ... and anyone, really ... what are your thoughts on the question in the "For discussion" section? Any guesses or ideas why?

13,067

Maybe the browser sends an "Accept:application/xml" ?

13,047

In addition, the default value in Postman is: */* - Any MIME type

 

12,949

I agree with @UweFetzer_se38... when using a browser, e.g. Firefox, it will send the following header - Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8. curl sends by default Accept: */*. You can see this when specifying the --verbose option, e.g. curl --verbose "https://services.odata.org/V4/Northwind/Northwind.svc/"

12,866

Yep, as you, @tobiasz_h and @ajmaradiaga have mentioned, it's all down to content negotiation. See this post (wow, that I wrote 20 years ago now) https://qmacro.org/blog/posts/2003/02/28/'conneg'-and-the-duality-of-weblogs./ for some background.

12,479

Thanks DJ for sharing another great blog.

In my case, I use Google's chrome browser, there is application/xml in the default rule of Accept attribute in the request header that why I got the XML content back.

discussion-request-header.png

btw, I completed this task via terminal, jq and Linux commands. That was so much fun indeed.

qmacro
Developer Advocate
Developer Advocate
12,399

Excellent, thanks for sharing, @bztoy! And I'm very happy to hear you approach solving this task in the way you did, on the command line 🙂 Glad it was fun!

Tomas_Buryanek
Active Contributor
0 Kudos
13,048

c12f340789fc51b1a128090ad3cea61dbf558ca7fc5aa0c4d499f0cd0ade1171

-- Tomas --

koehntopp
Product and Topic Expert
Product and Topic Expert
0 Kudos
13,035

749cbd3a2ee560aac2399b76fdc0e7091aa5aafe705a0beed07c945a59ee79db

fenna
Explorer
0 Kudos
12,960

eb083768b632bebd4e61247b06b8de96a073d0d06d02efd96a90b09932f4ef45

PriyankaChak
Active Contributor
0 Kudos
12,943

5e06cce278dfa322f00152bea18613418cf2faee23232a7362aaa8d7e3b5769b

nex
Explorer
0 Kudos
12,938

69b0efbd0f4180633ba7adff5d4f0e367ed98c6d43e2137ec3162b554aee45b1

SyambabuAllu
Contributor
0 Kudos
12,866

ce794b11a4987ec80938e616325e21ef7a5c7cfde00cf96f6e19730bb799fd78

marhol
Product and Topic Expert
Product and Topic Expert
0 Kudos
12,864

da3053b5058fa85f2ac71edf3a93131d1b6896dd81ddd59c476829705e1a0262

UweFetzer_se38
Active Contributor
12,856

If you want to solve this (and maybe one of the coming) tasks with ABAP, this blog post may help you: Ho To: Migrating from zjson to /ui2/cl_json 

qmacro
Developer Advocate
Developer Advocate
12,802

Thanks for sharing, @UweFetzer_se38 

Folks, this is definitely worth checking out

ceedee666
Active Contributor
0 Kudos
12,786
de6254b6813971755b7970853398745ef3abb4144410e6282e85bde1d56eefe4

TiagoAlmeida
Participant
0 Kudos
12,781

9697a49fa8134b57ead4931c755a59b06fee7d09fb6d9c745bc2aa069d9048e5

ceedee666
Active Contributor
12,793

Hallo @qmacro

is it OK to create Github repositories with solution code and share the link?

Christian

qmacro
Developer Advocate
Developer Advocate
12,699

That would be great, yes! Thanks.

ceedee666
Active Contributor
12,436

If anyone is interested my Python solutions are available here:  https://github.com/ceedee666/sap-dev-challenge-apis-in-python

qmacro
Developer Advocate
Developer Advocate
0 Kudos
12,415

Nice list comprehension action! 

entity_sets = [ v["name"] for v in r.json()["value"] if v["kind"] == "EntitySet"]