1
0
Fork 0

Fix #121: Refactor Mastodon.Http (#122)

* Drop use of Server args in ApiUrl.
* Generalize use of fetch to other Http functions.
* Leverage HttpBuilder.withQueryParams where applicable.
* Distinguish between request and authRequest.
This commit is contained in:
Nicolas Perriault 2017-05-03 08:52:39 +02:00 committed by GitHub
parent e673edb871
commit 89089b0ccf
2 changed files with 48 additions and 44 deletions

View File

@ -26,13 +26,14 @@ module Mastodon.ApiUrl
) )
type alias Server = apiPrefix : String
String apiPrefix =
"/api/v1/"
apps : String apps : String
apps = apps =
"/api/v1/apps" apiPrefix ++ "/apps"
oauthAuthorize : String oauthAuthorize : String
@ -47,7 +48,7 @@ oauthToken =
accounts : String accounts : String
accounts = accounts =
"/api/v1/accounts/" apiPrefix ++ "/accounts/"
account : Int -> String account : Int -> String
@ -92,12 +93,12 @@ following id =
homeTimeline : String homeTimeline : String
homeTimeline = homeTimeline =
"/api/v1/timelines/home" apiPrefix ++ "/timelines/home"
publicTimeline : String publicTimeline : String
publicTimeline = publicTimeline =
"/api/v1/timelines/public" apiPrefix ++ "/timelines/public"
accountTimeline : Int -> String accountTimeline : Int -> String
@ -107,12 +108,12 @@ accountTimeline id =
notifications : String notifications : String
notifications = notifications =
"/api/v1/notifications" apiPrefix ++ "/notifications"
statuses : String statuses : String
statuses = statuses =
"/api/v1/statuses" apiPrefix ++ "/statuses"
context : Int -> String context : Int -> String
@ -147,4 +148,4 @@ unfavourite id =
streaming : String streaming : String
streaming = streaming =
"/api/v1/streaming/" apiPrefix ++ "/streaming/"

View File

@ -36,6 +36,12 @@ import Mastodon.Encoder exposing (..)
import Mastodon.Model exposing (..) import Mastodon.Model exposing (..)
type Method
= GET
| POST
| DELETE
type alias Request a = type alias Request a =
Build.RequestBuilder a Build.RequestBuilder a
@ -74,16 +80,10 @@ toResponse result =
Result.mapError extractError result Result.mapError extractError result
type Method request : String -> Method -> String -> Decode.Decoder a -> Request a
= GET request server method endpoint decoder =
| POST
| DELETE
fetch : Client -> Method -> String -> Decode.Decoder a -> Request a
fetch client method endpoint decoder =
let let
request = httpMethod =
case method of case method of
GET -> GET ->
Build.get Build.get
@ -94,22 +94,25 @@ fetch client method endpoint decoder =
DELETE -> DELETE ->
Build.delete Build.delete
in in
request (client.server ++ endpoint) httpMethod (server ++ endpoint)
|> Build.withHeader "Authorization" ("Bearer " ++ client.token)
|> Build.withExpect (Http.expectJson decoder) |> Build.withExpect (Http.expectJson decoder)
authRequest : Client -> Method -> String -> Decode.Decoder a -> Request a
authRequest client method endpoint decoder =
request client.server method endpoint decoder
|> Build.withHeader "Authorization" ("Bearer " ++ client.token)
register : String -> String -> String -> String -> String -> Request AppRegistration register : String -> String -> String -> String -> String -> Request AppRegistration
register server clientName redirectUri scope website = register server clientName redirectUri scope website =
Build.post (server ++ ApiUrl.apps) request server POST ApiUrl.apps (appRegistrationDecoder server scope)
|> Build.withExpect (Http.expectJson (appRegistrationDecoder server scope))
|> Build.withJsonBody (appRegistrationEncoder clientName redirectUri scope website) |> Build.withJsonBody (appRegistrationEncoder clientName redirectUri scope website)
getAccessToken : AppRegistration -> String -> Request AccessTokenResult getAccessToken : AppRegistration -> String -> Request AccessTokenResult
getAccessToken registration authCode = getAccessToken registration authCode =
Build.post (registration.server ++ ApiUrl.oauthToken) request registration.server POST ApiUrl.oauthToken (accessTokenDecoder registration)
|> Build.withExpect (Http.expectJson (accessTokenDecoder registration))
|> Build.withJsonBody (authorizationCodeEncoder registration authCode) |> Build.withJsonBody (authorizationCodeEncoder registration authCode)
@ -130,54 +133,54 @@ send tagger builder =
fetchAccount : Client -> Int -> Request Account fetchAccount : Client -> Int -> Request Account
fetchAccount client accountId = fetchAccount client accountId =
fetch client GET (ApiUrl.account accountId) accountDecoder authRequest client GET (ApiUrl.account accountId) accountDecoder
fetchUserTimeline : Client -> Request (List Status) fetchUserTimeline : Client -> Request (List Status)
fetchUserTimeline client = fetchUserTimeline client =
fetch client GET ApiUrl.homeTimeline <| Decode.list statusDecoder authRequest client GET ApiUrl.homeTimeline <| Decode.list statusDecoder
fetchRelationships : Client -> List Int -> Request (List Relationship) fetchRelationships : Client -> List Int -> Request (List Relationship)
fetchRelationships client ids = fetchRelationships client ids =
fetch client GET ApiUrl.relationships (Decode.list relationshipDecoder) authRequest client GET ApiUrl.relationships (Decode.list relationshipDecoder)
|> Build.withQueryParams (List.map (\id -> ( "id[]", toString id )) ids) |> Build.withQueryParams (List.map (\id -> ( "id[]", toString id )) ids)
fetchLocalTimeline : Client -> Request (List Status) fetchLocalTimeline : Client -> Request (List Status)
fetchLocalTimeline client = fetchLocalTimeline client =
fetch client GET ApiUrl.publicTimeline (Decode.list statusDecoder) authRequest client GET ApiUrl.publicTimeline (Decode.list statusDecoder)
|> Build.withQueryParams [ ( "local", "true" ) ] |> Build.withQueryParams [ ( "local", "true" ) ]
fetchGlobalTimeline : Client -> Request (List Status) fetchGlobalTimeline : Client -> Request (List Status)
fetchGlobalTimeline client = fetchGlobalTimeline client =
fetch client GET ApiUrl.publicTimeline <| Decode.list statusDecoder authRequest client GET ApiUrl.publicTimeline <| Decode.list statusDecoder
fetchAccountTimeline : Client -> Int -> Request (List Status) fetchAccountTimeline : Client -> Int -> Request (List Status)
fetchAccountTimeline client id = fetchAccountTimeline client id =
fetch client GET (ApiUrl.accountTimeline id) <| Decode.list statusDecoder authRequest client GET (ApiUrl.accountTimeline id) <| Decode.list statusDecoder
fetchNotifications : Client -> Request (List Notification) fetchNotifications : Client -> Request (List Notification)
fetchNotifications client = fetchNotifications client =
fetch client GET (ApiUrl.notifications) <| Decode.list notificationDecoder authRequest client GET (ApiUrl.notifications) <| Decode.list notificationDecoder
fetchAccountFollowers : Client -> Int -> Request (List Account) fetchAccountFollowers : Client -> Int -> Request (List Account)
fetchAccountFollowers client accountId = fetchAccountFollowers client accountId =
fetch client GET (ApiUrl.followers accountId) <| Decode.list accountDecoder authRequest client GET (ApiUrl.followers accountId) <| Decode.list accountDecoder
fetchAccountFollowing : Client -> Int -> Request (List Account) fetchAccountFollowing : Client -> Int -> Request (List Account)
fetchAccountFollowing client accountId = fetchAccountFollowing client accountId =
fetch client GET (ApiUrl.following accountId) <| Decode.list accountDecoder authRequest client GET (ApiUrl.following accountId) <| Decode.list accountDecoder
searchAccounts : Client -> String -> Int -> Bool -> Request (List Account) searchAccounts : Client -> String -> Int -> Bool -> Request (List Account)
searchAccounts client query limit resolve = searchAccounts client query limit resolve =
fetch client GET ApiUrl.searchAccount (Decode.list accountDecoder) authRequest client GET ApiUrl.searchAccount (Decode.list accountDecoder)
|> Build.withQueryParams |> Build.withQueryParams
[ ( "q", query ) [ ( "q", query )
, ( "limit", toString limit ) , ( "limit", toString limit )
@ -192,50 +195,50 @@ searchAccounts client query limit resolve =
userAccount : Client -> Request Account userAccount : Client -> Request Account
userAccount client = userAccount client =
fetch client GET ApiUrl.userAccount accountDecoder authRequest client GET ApiUrl.userAccount accountDecoder
postStatus : Client -> StatusRequestBody -> Request Status postStatus : Client -> StatusRequestBody -> Request Status
postStatus client statusRequestBody = postStatus client statusRequestBody =
fetch client POST ApiUrl.statuses statusDecoder authRequest client POST ApiUrl.statuses statusDecoder
|> Build.withJsonBody (statusRequestBodyEncoder statusRequestBody) |> Build.withJsonBody (statusRequestBodyEncoder statusRequestBody)
deleteStatus : Client -> Int -> Request Int deleteStatus : Client -> Int -> Request Int
deleteStatus client id = deleteStatus client id =
fetch client DELETE (ApiUrl.status id) <| Decode.succeed id authRequest client DELETE (ApiUrl.status id) <| Decode.succeed id
context : Client -> Int -> Request Context context : Client -> Int -> Request Context
context client id = context client id =
fetch client GET (ApiUrl.context id) contextDecoder authRequest client GET (ApiUrl.context id) contextDecoder
reblog : Client -> Int -> Request Status reblog : Client -> Int -> Request Status
reblog client id = reblog client id =
fetch client POST (ApiUrl.reblog id) statusDecoder authRequest client POST (ApiUrl.reblog id) statusDecoder
unreblog : Client -> Int -> Request Status unreblog : Client -> Int -> Request Status
unreblog client id = unreblog client id =
fetch client POST (ApiUrl.unreblog id) statusDecoder authRequest client POST (ApiUrl.unreblog id) statusDecoder
favourite : Client -> Int -> Request Status favourite : Client -> Int -> Request Status
favourite client id = favourite client id =
fetch client POST (ApiUrl.favourite id) statusDecoder authRequest client POST (ApiUrl.favourite id) statusDecoder
unfavourite : Client -> Int -> Request Status unfavourite : Client -> Int -> Request Status
unfavourite client id = unfavourite client id =
fetch client POST (ApiUrl.unfavourite id) statusDecoder authRequest client POST (ApiUrl.unfavourite id) statusDecoder
follow : Client -> Int -> Request Relationship follow : Client -> Int -> Request Relationship
follow client id = follow client id =
fetch client POST (ApiUrl.follow id) relationshipDecoder authRequest client POST (ApiUrl.follow id) relationshipDecoder
unfollow : Client -> Int -> Request Relationship unfollow : Client -> Int -> Request Relationship
unfollow client id = unfollow client id =
fetch client POST (ApiUrl.unfollow id) relationshipDecoder authRequest client POST (ApiUrl.unfollow id) relationshipDecoder