swagger: '2.0'
info:
  version: '1.0.0-beta'
  title: MediaWiki Definition API
  description: Wikitionary word definition API
  termsofservice: https://github.com/wikimedia/restbase#restbase
  contact:
    name: Services
    email: services@lists.wikimedia.org
    url: https://www.mediawiki.org/wiki/Services
  license:
    name: Apache licence, v2
    url: https://www.apache.org/licenses/LICENSE-2.0
paths:
  /definition/{term}:
    x-route-filters:
      - path: ./lib/revision_table_access_check_filter.js
        options:
          title: term
          redirect_cache_control: '{{options.response_cache_control}}'
    get:
      tags:
        - Page content
      summary: Get term definitions based on Wiktionary content.
      description: |
        Experimental end point providing term definitions extracted from
        Wiktionary content. Currently, only English Wiktionary is supported.
        See [this wiki
        page](https://www.mediawiki.org/wiki/Wikimedia_Apps/Wiktionary_definition_popups_in_the_Android_Wikipedia_Beta_app)
        for background and considerations for further development.

        Stability: [stable](https://www.mediawiki.org/wiki/API_versioning#Stable)
      produces:
        - application/json
      parameters:
        - name: term
          in: path
          description: The term to define
          type: string
          required: true
        - name: redirect
          in: query
          description: >
            Requests for [redirect pages](https://www.mediawiki.org/wiki/Help:Redirects)
            return HTTP 302 with a redirect target in `Location` header and content in the body.

            To get a 200 response instead, supply `false` to the `redirect` parameter.
          type: boolean
          required: false
      responses:
        '200':
          description: The definition for the given term
          schema:
            $ref: '#/definitions/definitionsResponse'
        '301':
          description: |
            A permanent redirect is returned if the supplied article title was not in the normalized form.
            To avoid this kind of redirect, you can use the [mediawiki-title](https://github.com/wikimedia/mediawiki-title) library to perform
            title normalization client-side.

            Beware that redirected pre-flighted cross-origin requests (such as those sending custom request headers like `Api-User-Agent`)
            will fail in most current browsers [due to a spec bug](https://github.com/whatwg/fetch/issues/204).
        '302':
          description: |
            The page is a [redirect page](https://www.mediawiki.org/wiki/Help:Redirects).
            The `location` header points to the redirect target.
            If you would like to avoid automatically following redirect pages, set the `redirect=false` query parameter.

            Beware that redirected pre-flighted cross-origin requests (such as those sending custom request headers like `Api-User-Agent`)
            will fail in most current browsers [due to a spec bug](https://github.com/whatwg/fetch/issues/204).
        '404':
          description: Unknown term
          schema:
            $ref: '#/definitions/problem'
        '501':
          description: Term definitions not supported for this language
          schema:
            $ref: '#/definitions/problem'
        default:
          description: Error
          schema:
            $ref: '#/definitions/problem'

      x-setup-handler:
        # Set up a simple key-value bucket.
        - init:
            method: 'put'
            uri: /{domain}/sys/key_value/term.definition-ng
            body:
              valueType: 'json'

      x-request-handler:
        - storage:
            request:
              method: get
              headers:
                cache-control: '{{cache-control}}'
              uri: /{domain}/sys/key_value/term.definition-ng/{request.params.term}
            catch:
              status: 404
            return_if:
              # Typical case: Return straight from storage.
              status: '2xx'
            return:
              status: 200
              headers:
                content-type: '{{storage.headers.content-type}}'
                etag: '{{storage.headers.etag}}'
                cache-control: '{{options.response_cache_control}}'
              body: '{{storage.body}}'

        # Storage miss. Call mobile content service to get the definition.
        - extract:
            request:
              method: get
              uri: '{{$$.options.host}}/{domain}/v1/page/definition/{term}'
            response:
              # Define the response to save & return.
              headers:
                content-type: application/json
              body: '{{extract.body}}'
        - store:
            request:
              method: put
              uri: /{domain}/sys/key_value/term.definition-ng/{request.params.term}
              headers: '{{merge({"if-none-hash-match": "*"}, extract.headers)}}'
              body: '{{extract.body}}'
            # With the if-none-hash-match header the storage will return 412
            # if the content is not changed. In that case, return from the
            # handler completely, and avoid issuing purges.
            catch:
              status: 412
            return_if:
              status: 412
            return:
              status: 200
              headers:
                content-type: '{{extract.headers.content-type}}'
                etag: '{{store.headers.etag}}'
                cache-control: '{{options.response_cache_control}}'
              body: '{{extract.body}}'
        - emit_change_event:
            request:
              method: post
              uri: /{domain}/sys/events/
              body:
                - meta:
                    uri: //{request.params.domain}/api/rest_v1/page/definition/{request.params.title}
          response:
            return:
              status: 200
              headers:
                content-type: '{{extract.headers.content-type}}'
                etag: '{{store.headers.etag}}'
                cache-control: '{{options.response_cache_control}}'
              body: '{{extract.body}}'

      x-monitor: true
      x-amples:
        - title: Get definition from storage
          request:
            params:
              domain: en.wiktionary.org
              term: cat
          response:
            status: 200
            headers:
              etag: /.+/
              content-type: /^application\/json$/

definitions:
  definition:
    type: object
    description: Describes a single definition of a term
    properties:
      definition:
        type: string
        description: A term definition
      examples:
        type: array
        items:
          type: string
          description: An example of word usage
    required: [ 'definition' ]

  usageDescription:
    type: object
    properties:
      partOfSpeech:
        type: string
        description: Part of speech (e.g. 'Noun' or 'Verb')
      definitions:
        type: array
        items:
          $ref: definition
    required: [ 'partOfSpeech', 'definitions' ]

  definitionsResponse:
    type: object
    properties:
      usages:
        type: array
        items:
          $ref: usageDescription
    required: [ 'usages' ]
