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: 
A New Home in the New Year for SAP Community!

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

qmacro
Employee
Employee

(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?

222 REPLIES 222

ajmaradiaga
Employee
Employee

615e85240b2b40ad34999c0286eaccf6e2342ba9f97c16728430cea20773f3dc

That's what I call keen! Good work 🙂

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

tobiasz_h
Galactic 3
Galactic 3
0 Kudos

e9fd0523db9f34a66a2dbeb9ebc64b55a5ed17c344e6c0f3c47be2507e9c9a2e

VenugopalA
Galactic 2
Galactic 2
0 Kudos

c73f7c84c08796a400964d2641b24120e538eab527a97537be87070362600544

SandipAgarwalla
Galactic 4
Galactic 4
0 Kudos

0f01d357e485fd5c43f4faca9c214c023546cc245fc982fee0c5d4480fd59210

cguttikonda24
Galactic 3
Galactic 3
0 Kudos

741ca07242e615cc3d9d351ad5872d806250c8b4ab1135bf604cd18079a91e48

0 Kudos

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

0 Kudos

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.

 

 

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

0 Kudos

Hahah...True. Its an overkill.  😀

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

Compare your reply to replies from others in this thread 😉

0 Kudos

Got it...😮

se38
Galactic 4
Galactic 4
0 Kudos

206a0baa95d89bac061c1564cda3152e8b742ab0c4fc67aac7a72b1c179e854c

Eurey
Galactic 1
Galactic 1
0 Kudos

6cf3d2621ee5f4efb2aaf06d7a20eed1f3902ff2886843c7d5ec5c7a5cb4467c

emiliocampo
Galactic 3
Galactic 3
0 Kudos

2cbbe85945eade4a51d16ec7c4e5bae88ccc244a260baa9d66f572fc79182263

qmacro
Employee
Employee
0 Kudos

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

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

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

 

I agree with @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/"

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.

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.

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
Galactic 4
Galactic 4
0 Kudos

c12f340789fc51b1a128090ad3cea61dbf558ca7fc5aa0c4d499f0cd0ade1171

koehntopp
Employee
Employee
0 Kudos

749cbd3a2ee560aac2399b76fdc0e7091aa5aafe705a0beed07c945a59ee79db

Afenna
Galactic 1
Galactic 1
0 Kudos

eb083768b632bebd4e61247b06b8de96a073d0d06d02efd96a90b09932f4ef45

PriyankaChak
Galactic 3
Galactic 3
0 Kudos

5e06cce278dfa322f00152bea18613418cf2faee23232a7362aaa8d7e3b5769b

nex
Galactic 2
Galactic 2
0 Kudos

69b0efbd0f4180633ba7adff5d4f0e367ed98c6d43e2137ec3162b554aee45b1

SyamisUnique
Galactic 3
Galactic 3
0 Kudos

ce794b11a4987ec80938e616325e21ef7a5c7cfde00cf96f6e19730bb799fd78

marhol
Employee
Employee
0 Kudos

da3053b5058fa85f2ac71edf3a93131d1b6896dd81ddd59c476829705e1a0262

se38
Galactic 4
Galactic 4

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
Employee
Employee

Thanks for sharing, @se38 

Folks, this is definitely worth checking out

ceedee666
Galactic 3
Galactic 3
0 Kudos
de6254b6813971755b7970853398745ef3abb4144410e6282e85bde1d56eefe4

TiagoAlmeida
Galactic 2
Galactic 2
0 Kudos

9697a49fa8134b57ead4931c755a59b06fee7d09fb6d9c745bc2aa069d9048e5

ceedee666
Galactic 3
Galactic 3

Hallo @qmacro

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

Christian

That would be great, yes! Thanks.

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

0 Kudos

Nice list comprehension action! 

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