Skip to main content
Miso provides the Miso.Fetch module as a typed interface to the browser’s Fetch API. Functions are organized by the type of data being sent or received, and each integrates with miso’s Effect system via withSink.

JSON

The most common operations fetch or post JSON-encoded data.

getJSON

Retrieves a JSON response from a URL.
getJSON
  :: (FromJSON body, FromJSVal error)
  => MisoString                      -- ^ url
  -> [(MisoString, MisoString)]      -- ^ headers
  -> (Response body -> action)       -- ^ successful callback
  -> (Response error -> action)      -- ^ errorful callback
  -> Effect parent model action
Automatically sets Accept: application/json. On success the response body is decoded via FromJSON. On failure the error callback receives the raw response.

postJSON

Sends a POST request with a JSON-encoded body. Expects no response body.
postJSON
  :: (FromJSVal error, ToJSON body)
  => MisoString                      -- ^ url
  -> body                            -- ^ body
  -> [(MisoString, MisoString)]      -- ^ headers
  -> (Response () -> action)         -- ^ successful callback
  -> (Response error -> action)      -- ^ errorful callback
  -> Effect parent model action

postJSON'

Sends a POST request with a JSON-encoded body and expects a JSON response.
postJSON'
  :: (FromJSVal error, ToJSON body, FromJSON return)
  => MisoString                      -- ^ url
  -> body                            -- ^ body
  -> [(MisoString, MisoString)]      -- ^ headers
  -> (Response return -> action)     -- ^ successful callback
  -> (Response error -> action)      -- ^ errorful callback
  -> Effect parent model action
Automatically sets both Content-Type: application/json and Accept: application/json.

putJSON

Sends a PUT request with a JSON-encoded body. Expects no response body.
putJSON
  :: (FromJSVal error, ToJSON body)
  => MisoString
  -> body
  -> [(MisoString, MisoString)]
  -> (Response () -> action)
  -> (Response error -> action)
  -> Effect parent model action

Text

getText
  :: FromJSVal error
  => MisoString                       -- ^ url
  -> [(MisoString, MisoString)]       -- ^ headers
  -> (Response MisoString -> action)  -- ^ successful callback
  -> (Response error -> action)       -- ^ errorful callback
  -> Effect parent model action

Blob

getBlob
  :: FromJSVal error
  => MisoString
  -> [(MisoString, MisoString)]
  -> (Response Blob -> action)
  -> (Response error -> action)
  -> Effect parent model action

ArrayBuffer and Uint8Array

getArrayBuffer  :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response ArrayBuffer -> action) -> (Response error -> action) -> Effect parent model action
postArrayBuffer :: FromJSVal error => MisoString -> ArrayBuffer -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
putArrayBuffer  :: FromJSVal error => MisoString -> ArrayBuffer -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action

Image

postImage :: FromJSVal error => MisoString -> Image -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
putImage  :: FromJSVal error => MisoString -> Image -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action

FormData

getFormData  :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response FormData -> action) -> (Response error -> action) -> Effect parent model action
postFormData :: FromJSVal error => MisoString -> FormData -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
putFormData  :: FromJSVal error => MisoString -> FormData -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action

Header helpers

Convenience constants for building header lists:
-- Header names
accept      :: MisoString  -- "Accept"
contentType :: MisoString  -- "Content-Type"

-- MIME type values
applicationJSON :: MisoString  -- "application/json"
textPlain       :: MisoString  -- "text/plain"
formData        :: MisoString  -- "multipart/form-data"
octetStream     :: MisoString  -- "application/octet-stream" (internal)
Build headers with the =: utility from Miso.Util:
[(accept =: applicationJSON, contentType =: applicationJSON)]
User-supplied headers take precedence over any content-specific defaults that a Miso.Fetch function sets automatically.

The Response type

Response is defined in Miso.FFI.Internal and carries both the decoded body and metadata:
data Response body = Response
  { body         :: body
  , errorMessage :: Maybe MisoString
  , ...
  }
Both the success and error callbacks receive a Response, so status codes and error messages are always available even in the error branch.

Full example: fetching JSON in an update handler

This is the canonical pattern shown in the getJSON Haddock documentation:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE LambdaCase        #-}
module Main where

import Miso
import Miso.Fetch

-- | The data returned by the GitHub API
data GitHub = GitHub { login :: MisoString }
  deriving (Show, Eq)

instance FromJSON GitHub where
  parseJSON = withObject "GitHub" $ \o -> GitHub <$> o .: "login"

data Action
  = FetchGitHub
  | SetGitHub (Response GitHub)
  | ErrorHandler (Response MisoString)
  deriving (Show, Eq)

updateModel :: Action -> Effect parent Model Action
updateModel = \case
  FetchGitHub ->
    getJSON "https://api.github.com" [] SetGitHub ErrorHandler
  SetGitHub resp ->
    this .= body resp
  ErrorHandler err ->
    io_ (consoleError (maybe "unknown error" id (errorMessage err)))
The getJSON call is made directly in the update function. It returns an Effect that fires the sink with either SetGitHub or ErrorHandler once the HTTP response arrives.

Integration with withSink

All Miso.Fetch functions are built on top of withSink from Miso.Effect:
getJSON url headers_ successful errorful =
  withSink $ \sink ->
    FFI.fetch url "GET" Nothing jsonHeaders
      (handleJSON sink)
      (sink . errorful)
      JSON
This means they compose naturally with other Effect values and can be used anywhere an Effect is expected.

Servant integration

For more complex APIs modelled with Servant, use servant-miso-client to derive typed client functions automatically. Add it to your cabal.project:
source-repository-package
  type: git
  location: https://github.com/haskell-miso/servant-miso-client
  tag: master
See the Fetch example (live demo) for a complete working application.

Build docs developers (and LLMs) love