Git Product home page Git Product logo

fred-api's People

Contributors

bobjolliffe avatar edjez avatar mberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fred-api's Issues

Need a way to query location hierarchy

The current specification currently deals with querying facilities, and in 1.1, hierarchies of facilities. But a lot of countries have ambiguities around the names of districts, and the existence of names of sub-districts, which can contain facilities. As part of 1.1, we should discuss how facility registries plan to share this kind of location metadata, possibly as part of a broader discussion of other kinds of facility metadata we want to be able to share.

Explicitly document lat/long order

In the geolocation section, we use GeoJson derived coordinates:

coordinates: [-1.6917, 29.5250]

The spec doesn't say whether the first number is latitude or longitude. This should be added briefly to avoid ambiguity.

  • Chris, Morten, Bharti

versioning proposal

Comment submitted by Chris Ford on mailing list 2012/11/14

I was thinking about the versioning discussion we were having earlier, and I'd like to suggest a compromise that would allow us to avoid the complexity of content negotiation, but still keep our URLs fairly stable. The trick is to mint URLs only on breaking changes.

The strategy can be summed up in these rules:
Clients MUST ignore fields they do not recognise.
Content-Type identifiers MUST include a version number with major and minor versions (e.g. application/fred.facility.v1-5+json, application/fred.collection.v2-0+json) and MUST be backwards compatible with other versions with the same major and lower minor version numbers.
Servers MUST serve a Content-Type response header along with successful (2xx) responses.
Servers MAY increment the minor version number of content they serve at a particular URL.
Servers MUST use a new URL if they increment the major version number of content.
If these rules are obeyed, we can easily make expanding change to the API without content negotiation or breaking existing clients. Backwards-incompatible changes will require a new URL-space and will cause existing links to point to old API versions, but this will be comparatively infrequent (and perhaps will never happen). Clients who encounter older versions of the service than they expect will be able to use the Content-Type to work out which elements not to rely on.

A simple way for servers to implement a new URL-space per major version would be to include "v1", "v2" etc in all URLs, but this should not be part of the published contract, otherwise clients would rely on details of URL structure.

Return more data on facility creation

Currently the spec says that the server should return the facility URL when a facility is created. (DHIS2 does this with the Location header. This should probably be explicitly specified in the spec.)

DHIS2 also returns the URL of a human-readable page. Since there is no defined format for URLs with respect to IDs, there is no way to get the ID of a newly created facility.

The spec should be changed to either:

  • the URL returned must be to the JSON representation of the facility. The client can then make an additional request to get data about the new facility.
  • or better, the response body should contain the JSON representation of the core properties of the facility. This also ensures that other core properties like createdAt and updatedAt are known to the client.

Sorting

Sorting

/facilities.json?sortAsc=beds&sortDesc=nurses

Sorts the results by property.

.. Note::

  • Each field type needs to define what ascending/descending means.
  • Sorting precedence is left to right (first by beds then by nurses in the example above) - closest to the “?”

Use "list" property type instead of "select"

The "Implementation Specific Properties" has several types that custom types can be built out of. One of them is "select", which is a little confusing as it appears to relate to a UI element, perhaps HTML?

Could this be specified as a list that contains instances of the other simple types?

Or at least could the meaning of this type have more explanation?

  • Chris, Morten, Bharti

Remove filtering etc from API version 1.0

I suggest we omit property filtering, counting, pagination, search and sorting from the initial version of the facilities API.

This will simplify implementation and allow us to come to agreement on the API more quickly. Adding these refinements can be done at a later date in a backwards compatible way.

I am not sure about filtering by updated_since. If we want to allow consumers of the API to maintain a mirror of the facilities so that they can operate without connectivity, then we may need a way to allow them to check for changes so they can selectively update. This is the case in Uganda.

In Create Facility spec, issue with required fields

It says:
The body can’t be empty and must include at least the name attribute, a string that will be used as the name of the facility.

One would expect it to say: the body can avoid the name attribute if it has other stuff. Of course hopefully people would not send an empty document.

Improve language

"All dates/timestamps should be in ISO 8601 and include a timezone (default UTC)"

This is vague and seemingly contradictory.

hierarchy support

DHIS2 has implemented hierarchy's within FRED this way.

Do we want to follow this format?

This would require specification of the level and parent along with the hierarchy block.

Within the block we'd probably want to agree upon use of id, level, name. Should URL be supported or implementation specific?

level: 4,
parent: "hRZOIgQ0O1m",
hierarchy: [
{
    id: "H1KlN4QIauv",
    level: 1,
    name: "National",
    url: "http://apps.dhis2.org/dev/api/organisationUnitLevels/H1KlN4QIauv"
},
{
    id: "wjP19dkFeIk",
    level: 2,
    name: "District",
    url: "http://apps.dhis2.org/dev/api/organisationUnitLevels/wjP19dkFeIk"
},
{
    id: "tTUf91fCytl",
    level: 3,
    name: "Chiefdom",
    url: "http://apps.dhis2.org/dev/api/organisationUnitLevels/tTUf91fCytl"
},
{
    id: "m9lBJogzE95",
    level: 4,
    name: "PHU",
    url: "http://apps.dhis2.org/dev/api/organisationUnitLevels/m9lBJogzE95"
}
]

Meta Summary Data?

So what is the point of this? It seems to be related to paging, but I see that the paging parameter is now removed.

Does it make sense to have this anymore, or should it be removed? or at least the example should be changed to an actual use-case of this block.

Paging: rename limit=off to limit=0

I suggest this so that we have less confusion. Right now its hard to understand what limit=off means with regards to the offset parameter.

I suggest limit=0 means no limit.

Define what results in a duplicate facility 409 - Conflict response

The spec for create currently says: "If duplicate is detected a 409 is returned"

but doesn't define what a duplicate is.

I think one of the provider implementations I've been testing against considered having the same name to be enough to consider a facility a duplicate, but that doesn't seem robust.

Same name and coordinates?

Is it left up to the implementation? If so, that should be stated.

Mandatory timezones

Previously I suggested that if we're using ISO 8601 dates, then we should additionally at the restriction that it should be an ISO 8601 date with a specified timezone. It seems that mention of timezones has been removed from the spec in the latest version.

If we don't have a timezone, then ISO 8601 says that it should be interpreted as "local time", which is not a sound concept when we're talking about distributed system.

In fact, though I did earlier suggest a compromise that we only recommend UTC, could we make things simpler and mandate UTC? Translating between timezones is complexity we should keep out of the API.

Meta Summary Data

Meta Summary Data

Results return a meta block of summary resultset data to make client application development easier. This is an optional feature to the core API.

meta: {
    limit: 2, next: null, offset: 0, previous: null, total_count: 29
},

Move MOH_ID, UNICEF_ID, X_ID to just ID

Hello Again,

When doing the formal documentation draft I encountered the MOH_ID, UNICEF_ID elements and thought this seems like a rather odd way of representing muliple identifiers. I would propose that these be consolodated as "identifiers" or simple "id" with the agency element populated.

The rationale behind this is simple best practices when programming. Rarely do programmers write code fields: home_address, work_address, work2_address, etc. rather it is better practice to create an array of address with a type classifier. My suggestion is change:

<moh_id agency="moh" id="123"/>
<unicef_id agency="unicef" id="321"/>

to

This solution is much cleaner and is closer to existing standards.

Cheers
-Justin

UTF-8

I think that everyone will be using UTF-8 anyway, but can we please mandate it so that we are sure we won't end up with annoying encoding errors?

Clarify facility creation response format

The spec currently defines the JSON format for a facility response as:

{
   "facility": {
       "name": "Kakamega HC",
       ...
   }
}

I believe the implementations I've been testing against simply return the bare facility object. I propose switching the spec to that unless someone can provide a plausible future use-case for additional keys in the facility creation response that wouldn't be better accomplished with HTTP headers and also justify why that format couldn't just be adopted when it became necessary instead of now -- it seems like any additional properties might warrant a version bump anyway?

Remove URL structure from the specification

Currently, the collection format includes a URL to each individual facility. Any consumer of the service can take a collection of facilities and follow the URLs to individual facilities.

However, we go further in the current specification, and describe the format of the URL of both the collection and individual facilities, e.g.:

/facilities
/facilities/123

I propose that we don't include URL structure as part of the API contract, thus loosening the coupling between consumer and service a little. Services are still free to use the URL structure if they want, but consumers shouldn't depend on it.

For example, exposing the structure of the URL as part of the contract would prevent anyone from exposing a "mashup" list of facilities from multiple registries.

Rwanda and Uganda might keep track of their own list of facilities, but it could be useful to provide a list of facilities that are involved in a cross-border campaign. If we tell consumers of the API that they can construct URLs of individual facilities from the URL of the collection, this is not possible, because a facility has to be hosted on the same registry as the list.

Allowing arbitrary URLs also gives a way to do filtering, search etc without including it explicitly in the first draft of the API e.g. we could expect all the following URLs to work, so long as they return the correct collection format:

/facility-search?q=foo
http://www.world-wide-fred.com/all
/campaigns/polio-vaccine/participating-facilities

I'd be interested to hear about the advantages of specifying URLs to balance the above points...

Mandatory URL parts?

We've discussed previously the URLs in the spec, and I think have reached the conclusion that they are examples only - #5.

However, the individual facilities URLs seem to imply that an implementation must use the id field when constructing the individual facility URL, which I didn't think was true:

/facilities/<id>.json

Would it be clearer that it's an example if we put the following?

/facilities/0X9OCW3JMV98EYOVN32SGN4II.json

I think the spec is still a bit confusing as to what is an example and what is actually part of the API.

Seems to me that the mandatory things are:

  • ?allProperties=
  • ?fields=
  • ?updatedSince=
  • ?active=
  • .json
  • major version being somewhere in the URL

Is that everyone else's impression? If so, can we call them out explicitly?

Improve language re JSON

The spec currently says:
"The initial API implementation will support only JSON. Once the API stabilizes, support for an XML endpoint is planned."

It is pointlerss making reference to things like the "initial API implementation". At some point in the future someone will just be looking at this document. So we keep it simple. What we mean is:
"This document defines an API which uses JSON (http://www.json.org).for exchanging data."

What is planned or not planned is not really helpful to understand this document. But if anywhere, future plans should be in "Future API Features" section.

(In a separate issue I will propose dropping that section anyway. it is highly unusual to highlight the features of the next version of a spec in the current version. For good reason.)

Partial updates

Currently, our only update mechanism is PUT. As per the HTTP spec, PUT requires the entire resource to be supplied. We could allow clients to POST to the facility URL, and only update the supplied top-level keys.

This would be of benefit to clients who only persist and care about certain fields. If, for example, I had a client that only existed to put facilities on a map, it might not care about anything other than name and geo-coordinates.

However, unless we allow partial updates, that client would need to process everything else a facility might have, or else risk inadvertently deleting data or having the update rejected.

Query: URL format?

The spec is inconsistent as to whether .json appears on the end of URLs. For updating a facility, there's no .json, but for reading them, there is.

Also, in the example, the URL to the facility doesn't have the extension.

This seems inconsistent.

  • Chris, Morten, Bharti

Clarification : Post Facility

Another clarification for the formal documentation.

What are the thoughts around the POST (or creation) of a duplicate facility record. I am trying to clarify in my mind the expected behavior of a facility registry implementation.

In a perfect world, the facility registry should be capable of acting like IHE PIX managers do. That means whenever a duplicate record is detected (for example, FR already has a facility with the same name, same geo-location, and same MOH id) it should merge the records. The rationale for this is simple; places the onus of detecting duplicate entries with the registry which has knowledge of ALL facilities registered in a jurisidiction (or at least it is a more central authority) and centralizes the logic for matching / detecting duplicates. This is helpful as legacy systems "come online" and need to migrate their data in batch.

From what I've read this is not the case. Based on my interpretation of the verbiage on the FR API docs, the FR is to return a 409 if a duplicate exists (although this is not really clear). Is this true or does the FR simply create a new record? IMO placing the onus on the client to determine if a facility has already been registered prior to registering the facility can be problematic, and may lead to inconsistent implementations of duplicate resolution.

I am ok with either solution, I just need clarification so I can clearly write the specification document in an unambiguous way.

Filtering

Filtering Facilities

/facilities.json?property1=value&property2=value

Properties apply to all core and user defined facility properties

Dates should have a timezone

For e.g. Created At, we say we should use ISO 8601. However, this spec doesn't mandate a timezone. When there is no timezone, "local" time is used, which isn't suitable for a client/server app.

Could we mandate specifying a timezone? Or at least suggest one?

  • Chris, Morten, Bharti

PS The wikipedia link to ISO 8601 has a trailing slash, which breaks it.

Pagination

Pagination

/api/features.json?limit=25&offset=50
  • limit: the amount of records to return in a result. Default = ??
  • offset: the offset of the search result. Facilitates pagination
  • paging=false: turns pagination off

Default value of active (true)

Hi

In the current spec, it says that only name is required. But it does not give the default value for active. I'm assuming this is true ? If so, it should be in the spec.

Renaming created_at / updated_at

The naming convention created_at / updated_at breaks the normal naming convention used in JS, a better naming scheme would be createdAt, updatedAt, since camelCase is the norm for JS.

I assume created_at / updated_at reflects your ruby / python backend, which is fine, but for the JSON, I at least would prefer using normal camelCase notation.

Remove References to "CHP"

The document seems to make a few references to "CHP" content, documentation and backstory.

We should aim to define the appropriate few terms that are needed locally - HIX, actor/role, etc- and document the few required interactions locally, since the references to other docs seem not to add value.

Standardise unique id generation on RFC 4122

My understanding of the purpose of the id field is to provide an identity that allows facilities data to live beyond the original system it's hosted in. To achieve this, the id must:

  • Have no collisions, so that lists of facilities can be merged
  • Not be dependent on the URL, so that facilities can be hosted in a new location
  • Be generated in a well-understood way, so new ids can continue to be created if facilities are migrated to a new system

In #26 we resolved that the intention of the id was to be "universally unique". The spec also says that "the API does not providing a specific format for IDs".

There's a contradiction between these two ideas, because UUIDs are only unique within the scheme that created them. So two facilities registries using different UUID generation schemes could unwittingly experience collisions. So if we don't agree on how the ids are generated, we admit the possibility of collisions.

But the pressing practical reason I have for wanting to standardise on RFC 4122 is to port the generation of ids to a new system. On a project I'm involved in, facilities are being hosted in DHIS2, but will be migrated to a different system. If the scheme for id generation isn't reproducible within the new system, then how can the new system create new facilities?

By picking RFC 4122 and using its standard string representation (e.g. '5899d128-4c55-11e2-b5e1-b88d12122fdc'), we get a well-understood, widely supported and robust scheme for id generation.

Cheers,

Chris

Rename url => href

I think the url field should be renamed to href, this will keep it more in sync with what people are used to from other APIs.

Clarification : Delete

Hello All,

I'm just requesting some clarification/suggestion on one of the operations in the FRED operation contract. The DELETE verb in the API docs posted on the internet it states that DELETE deletes a registry from the facility registry.

May I suggest that we dont use this verbiage in the formal documentation and instead refer to it as an obsoletion (or logical deletion). My rationale is two fold on this:

  1. You should never actually delete data that can be linked from another service. For example, if I have a provider registry which links to facility 123 on a FRED instance as "primary place of work", and some other system deletes 123 on the FRED instance, my data is not inconsistent.
  2. Obsoletion is more often used in most other registries and is more consistent with existing standards.

What I am proposing in the formal documentation is that obsoleted facilities should not be discoverable (i.e. should not be returned in queries), however should be retrievable via a direct GET against the resource. I have not specified how this is to be done internally, however at a wire level the operation should use the DELETE verb (it is a logical deletion).

Cheers
-Justin

rethink url core property

What is the purpose of having a URL field if it just contains a URL that can be programmatically generated from the facility ID and base API url?

The spec requires the major version number to be exposed in the URL. This would probably result in, if not be expressly be for the purpose of allowing, providers giving access to the same set of facilities through multiple base API urls for clients implementing different major versions of the API. Would the two endpoints return different URLs in a facility response for different API versions? That seems to go against the idea of core properties being canonical data.

I propose we require URL to be to a human-readable representation of the facility if one exists, and otherwise it should be left out.

UUID / Url Templating

Chris and I (Morten) are suggesting two new changes to the API.

  • The id field is renamed to uuid
  • The uuid field MUST be a valid UUID as per RFC 4122 using the default string representation (in other words, a conventional UUID).
  • If the url of a facility changes, e.g. the registry moves to another domain, then the uuid must remain constant.
  • The url of a facility MAY be structured around the uuid, a system-specific identifier or some other scheme.
  • Clients of the facilities registry MUST use the provided url field and not attempt to calculate the URL themselves from other fields the facility has.
  • This would allow us to have the benefits of UUIDs for migration, federation etc, while making it more self-evident of the intent of the uuid field.

Encouraging clients to use the provided url is simpler and less-error prone, as well as giving us as API designers more flexibility as to how we link a facilities registry with a broader system.

We would then have two fields, each with a clear purpose and semantics - url for locating a facility, and uuid for identity.

  • Chris, Morten

Using GUIDs for IDs

Currently the spec allows IDs to not be globally unique. The FRED specification says that "the system will not return the same system id twice when creating two facilities", but ids might clash between registries.

This can cause a problem in the following situations:

  • An index that refers to facilities in multiple countries e.g. Rwanda and Uganda.
  • While merging the list of facilities from more than one registry.
  • When migrating facilities from one registry to another. (This is a problem for our current project in Uganda).

We suggest that IDs should be 128 bit GUIDs. This will avoid all problems of ID clashes between different systems. Libraries for generating GUIDs are easily avaialble for all platforms and programming languages.

Implementations would be free to choose shorter IDs to include in URLs because they control the namespace of URL and therefore there is no chance of collision.

We haven't been able to catch up with Morten about this yet. Hopefully this will chime in with his perspective shortly.

-Bharti & Chris

date_closed & open_date

Do we want to support the idea of a date_closed and open_date as core properties?

I believe Bob said this is an important component of DHIS2

Use an index for collections of facilities

Rather than include all the facility information in a collection, could we use a simple index of links and summaries to all the available facilities?

The index could use Atom, or a similar format.

This would have the following advantages:

  • We separate out the two problems of listing and describing facilities, thus simplifying each representation.
  • It would be easier to add new collection concepts, for example we might implement hierarchies by allowing collections to link to both individual facilities and collections of facilities, and we wouldn't have to overload further the facility format.
  • Clients can load index information about facilities without having to load each facility.
  • We might be able to cache the index and individual facilities separately.

Apologies if this has already been discussed.

/facilities.json?properties=all

It's not specified, but should you be able to do properties=name here? and so on? is it basically a boolean, so maybe it should be changed to properties=true ? (same as active)

Single format

The facilities registry data is currently to be returned in both XML and JSON format. I suggest that we pick one.

Requiring support for a single format makes it easier to build new API implementations. Supporting two formats opens the possibility for subtle differences in specification or implementation.

The disadvantage of this proposal is that consumers of the API who prefer the unsupported format will need to work with the one that is, but I'm not aware of any programming environment we would be totally excluding if we went with a single format.

My personal preference is JSON, as to me it is a simpler data exchange format, though I think XML-only would be better than both.

Question about Counting

Another question, what is the purpose of the count operation? I'm trying to come up with some samples/description for count and the only use case I can think of is getting the total number of facilities matching a particular filter (example, for doing a progress bar). Is this correct?

If so, may I ask the rationale for doing it this way? It seems like a pretty chatty.

GET /facilities/count.xml?name=Good%20Health
GET /facilities.xml?name=Good%20Health

Is there a use case where a client application would want to count the number of facilities without actually getting them? Maybe I'm just stuck on a query use case :)

Perhaps adding the meta-data for the query results might be a better solution. For example (adapted from the current docs)

 <fac:queryAck>
     <fac:current>2</fac:current>
     <fac:offset>0</fac:offset>
     <fac:total>20</fac:total>
 </fac:queryAck>

Cheers
-Justin

errorMessage.code can be a number?

Hi

It seems that in the spec message.code is required to be a string, since both the status code + status message is used.

Can/should this be changed to only status code? it makes sense, yes? If you want to say, "bla bla not found" you can do so in the message part.

Multiple values for sort key

Hi all!

We found an issue with the specs of sorting criteria.

Let's say I want to sort by beds 'asc' and then by nurses 'asc'. According to the current specification, I should send this query:

/facilities.json?sortAsc=beds&sortAsc=nurses

Then the 'sortAsc' query key would be duplicated, and the way that's interpreted by default varies depending on your choice of language and/or framework.
(You can take a look at a discussion on the topic at: http://stackoverflow.com/questions/1746507/authoritative-position-of-duplicate-http-get-query-keys).

In order to avoid this issue we suggest to change the specification so the query is performed in the following way in future versions of the API.

/facilities.json?sort=beds:asc,nurses:asc,numServices:desc
(sorting precedence from left to right)

This would be interpreted as a plain string regardless of languages and frameworks. We think this is better because in general it's much easier to parse a string than to modify the default URI parsing behavior of the underlying framework.

And this way we can get around the limitation on sorting parameters.

Does this sound good to you?

Suggest servers support gzip, etags and cache headers

We don't need to make this mandatory, but from our conversations on the other issues it seems that bandwidth usage is a common concern. These three standard HTTP elements can cut down on unnecessary data transfer.

They can be suggestions rather than mandatory, and standard HTTP request headers will let servers and clients take advantage of these features assuming both support it. In fact, servers could very well decide to provide these features under the current spec.

Cache headers especially could be useful, as a common use case seems to be maintaining a mirror of facility information.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.