From 371dc9489c1c03956f0cb8e1c03d7592f8c0f419 Mon Sep 17 00:00:00 2001 From: Peter Sanchez Date: Fri, 27 Dec 2024 10:41:41 -0600 Subject: [PATCH] Adding base graphql document --- graphql.md | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++++ index.md | 5 ++ 2 files changed, 250 insertions(+) create mode 100644 graphql.md diff --git a/graphql.md b/graphql.md new file mode 100644 index 0000000..453551c --- /dev/null +++ b/graphql.md @@ -0,0 +1,245 @@ +--- +title: 'LinkTaco API (GraphQL)' +description: 'Using the LinkTaco API (GraphQL)' +--- + +LinkTaco offers an API for our services via [GraphQL](https://graphql.org). +This page documents the traits our GraphQL API. + +# Attribution + +Our GraphQL setup is heavily based on the [SourceHut][srht] GraphQL services. +As such this document is a modified version of the [original SourceHut +document][srht og]. + +[srht]: https://sourcehut.org "SourceHut" +[srht og]: https://man.sr.ht/graphql.md "SourceHut GraphQL" + +# API Info + +The API is accessed via the location `https://api.linktaco.com`. + +All requests must be sent as a POST request the `/query` endpoint. + +# GraphQL playground + +LinkTaco offers a "playground" where you can run GraphQL queries to test +and learn about the system. The canonical reference for each GraphQL schema is +also available in the playground. + +**NOTICE**: The GraphQL playground is wired up to your *production* data. Any +queries you perform will affect your real data! + +- [GraphQL Playground](https://linktaco.com/graphql) + +# Authentication strategies + +GraphQL authentication is based on OAuth 2.0 and is compatible with +[RFC 6749][RFC 6749]. Detailed documentation on our OAuth 2.0 implementation is +available in the [oauth documentation][oauth]. + +[RFC 6749]: https://tools.ietf.org/html/rfc6749 +[oauth]: oauth.md + +In short, there are two primary modes of authentication: + +- Personal access tokens +- OAuth Bearer tokens + +The former is suited to users who are writing their own scripts, CLI programs +with no web component, and so on. Personal access tokens are available from +[linktaco.com/oauth2/personal](https://linktaco.com/oauth2/personal). + +The latter is useful for third-parties who wish to provide a streamlined +authentication process. You should first register for an OAuth 2.0 client at +[linktaco.com/oauth2/clients](https://linktaco.com/oauth2/clients). For +details, consult [RFC 6749][RFC 6749] and the [meta.sr.ht documentation][meta +oauth]. + +In either case, once a token is obtained, it is used by setting the +`Authorization` header to `Bearer `, e.g. +`Authorization: Bearer AI+ym2EAAAAAAAAIc2lyY21wd26a8JLR48pyNs2ImxWYjgi9YVGxssyt5qk4YyV7BhHXAg` + +## Access scopes + +It is possible (and strongly encouraged) for the user to limit the scope of +access that is provided by an authentication token. The access scopes supported +by LinkTaco, and the required scopes to utilize each resolver, are +documented in the [GraphQL schema][gql schema]. + +[gql schema]: https://git.code.netlandish.com/~netlandish/links/tree/master/item/api/graph/schema.graphqls "GraphQL Schema" + +They can also be requested programmatically by fetching the following URL: + +https://api.linktaco.com/query/api-scopes.json + +The following scopes are available for use: + +- PROFILE +- LINKS +- LISTS +- SHORTS +- ORGS +- DOMAINS +- BILLING +- ANALYTICS +- QRCODES + +The access kind is either `RO` or `RW`; respectively referring to read-only or +read/write access to that scope. If no access kind is provided with the scope +the API will assume `RO` (read-only). + +Example: `PROFILE:RO LINKS:RW ANALYTICS:RO` + +More detailed information on using access scopes is available in the [OAuth2 +documentation][oauth]. + +# Performing GraphQL Queries + +The GraphQL API accept queries at `/query`. To perform your query, +submit a JSON payload to this endpoint as an HTTP POST request with the +following schema: + +```json +{ + "query": "your GraphQL query...", + "variables": { + "foo": "bar" + } +} +``` + +The `variables` field is optional, if your query requires no variables. A simple +query which is supported on all APIs is: + +```json +{ + "query": "{ version { major, minor, patch } }" +} +``` + +Your request shall have the `Content-Type` set to `application/json`. + +## Requesting with cURL + +Here is a simple request: + +```sh +oauth_token=your oauth token +curl \ + --oauth2-bearer "$oauth_token" \ + -H 'Content-Type: application/json' \ + -d '{"query": "{ version { major, minor, patch } }"}' \ + https://api.linktaco.com/query +``` + +Obtain a personal access token from +[linktaco.com/oauth2/personal](https://linktaco.com/oauth2/personal). See +[Authentication strategies](#authentication-strategies) for details. + +## Uploading files + +Some GraphQL resolvers accept file uploads, via the `Upload` type. Our +implementation is compatible with the [GraphQL multipart request +specification](https://github.com/jaydenseric/graphql-multipart-request-spec). + +# Query complexity limits + +To limit abuse, we calculate the complexity of your query before executing it, +and apply an upper limit. As a general rule of thumb, the complexity is +a function of how many resources your request implicates. + +Each field adds 1 to your complexity, unless it represents a relationship +— in which case it is multiplied by the number of results you request. +The total complexity of your request is capped to 200 by default. + +Additionally, the total time spent processing your request is capped to 3 +seconds by default, though more time is permitted for resolvers handling file +uploads. + +## Cursors + +The number of results returned from a cursored resolver is limited to a certain +cap, and is used to spread your work out over several requests. Consider this +example: + +``` +query { + getFeed { + result { + title + url + description + author + orgSlug + createdOn + tags { + name + slug + } + pageInfo { + cursor + hasPrevPage + hasNextPage + } + } + } +} +``` + +The `cursor` field returns an opaque string which can be used to return +additional results, or `null` if there are none. The following request returns +another page: + +``` +query GetFeed($after: Cursor, $before: Cursor) { + getFeed(input: {after: $after, before: $before}) { + result { + title + url + description + author + orgSlug + createdOn + tags { + name + slug + } + pageInfo { + cursor + hasPrevPage + hasNextPage + } + } + } +} +``` + +You may perform repeated GraphQL queries to obtain all results. The default +limit for results returned from a single request is 40. Some resolvers accept a +`Limit` value on the specific "Input" parameter which allows you to request a +different number of results — be aware of the complexity limits while +tuning this number. + +# API stability guarantees + +The `version` resolver provides API versioning information which is compatible +with [semantic versioning](https://semver.org). The *major* version increments +when the API is changed in a backwards-incompatible way; *minor* when new +features are added, and *patch* when bugs are fixed. Changes presumed to be +backwards-compatible include: + +- Adding new types +- Adding new resolvers +- Adding new fields to existing types +- Adding new members to enums +- Adding new optional parameters to existing resolvers +- Adding new optional fields to existing input types + +The special version `0.0.0` indicates an API which is still undergoing its +initial design work, and provides no stability guarantees whatsoever. + +An additional field is provided by the `version` resolver: `deprecationDate`. +The field, If not null, indicates the date at which a major +version increment is planned. Interested parties may want to monitor this value +and incorporate it into their planning. diff --git a/index.md b/index.md index a18555d..76a12be 100644 --- a/index.md +++ b/index.md @@ -12,6 +12,11 @@ description: 'Documentation for the software and usage of LinkTaco' - [Import / Export Data](import-export.md) - [Custom Domains](custom-domains.md) +# API / GraphQL + +- [OAuth 2 Implementation](oauth.md) +- [GraphQL API](graphql.md) + # Technical / Development * [How to Build](build.md) -- 2.45.3