3

I'm designing a REST API to be the back-end of a push notification service. The actual push notifications will be handled via Firebase Cloud Messenger (FCM)

So, the external client needs to be able to subscribe to certain objects in my back-end with their FCM ID.

My first attempt was something like

  • GET /subscriptions/{deviceId} - get list of subscriptions
  • PUT /subscriptions/{deviceId}/myObject/{objectId} - subscribe to object with id objectId of type myObject (type of subscription as body)
  • DELETE /subscriptions/{deviceId} - delete all my subscriptions

However, there are two problems with this. Both are connected to the form of the deviceToken from FCM:

  1. One is very practical: the deviceToken can (and does) include a colon. We use WS02 API Manager as an API Gateway. It doesn't like colon in a path parameter - you get a "not found" from the gateway without the request ever reaching the underlying API. URL-encoding the colon doesn't help
  2. The other is more theoretical: Google don't specify a max length for the FCM IDs anywhere. (see this answer) so it could be up to 4k long, which is longer that the URL is allowed to be :) In practice, it seems to be under 200 characters at the moment

Options I have come up with:

  • Base64 encode the ID and use in the URL. Seems unnecessary extra work at both ends and doesn't help with the length
  • Make it a query parameter instead of path parameter. Doesn't seem fully "correct" in terms of REST principles and doesn't help with the length
  • Make the GET and DELETE requests into POSTs (or PUTs) with the deviceId in the body and :get or :delete at the end of the URL. This is, as I understand it, a fairly common way of issuing commands via REST (and probably why the WS02 API Manager worries about colon when parsing the path). Seems slightly wrong for DELETE and very wrong for GET. But solves both problems.
  • I suppose the other option is to generate my own ID, returned from the initial PUT, but that doesn't seem right either. Introduces an extra data element to keep track of at both ends just to get round the URL limitations.

Any other ideas? Any recommendations? How have people handled overly long or complex IDs in REST URLs?

Adam
  • 6,539
  • 3
  • 39
  • 65
  • 1
    Your API looks well designed. API consumers won't care about which ID you use hence your fourth bullet point is possibly the cleanest one if you want to stay with REST. You say "that doesn't seem right" though I can't see any issue with it. The FCM ID isn't a resource key for your objects. It's a subscription ID for a specific purpose: subscribing. If you get your head free from the FCM ID being the resource ID, which in my humble opinion is wrong, then you're also free to see the simplest solution for the problem :) – Quality Catalyst Feb 04 '18 at 21:49
  • Thanks. I guess I felt it was unnecessary to force the client to track two IDs and the relation between them instead of just one. I wanted the client to be able to say "I want this type of message sent here" and that's it. But I do see your point. However, despite it's drawbacks I've gone the Base64 route for now. This is mainly due to project constraints - it's requires no re-engineering outside of the API. I will revisit this in the future though – Adam Feb 05 '18 at 21:00

0 Answers0